home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / utilitys / bmake_06 / part01 next >
Encoding:
Internet Message Format  |  1991-07-04  |  71.9 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i123: bmake 0.6 - automate recompiling multiple source files, Part01/03
  4. Reply-To: ENG  BENNY <engb@ecf.toronto.edu>
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga.v91i123@ab20.larc.nasa.gov>
  7. Date: 04 Jul 91 16:38:42 GMT
  8. Approved: tadguy@uunet.UU.NET (Tad Guy)
  9. X-Mail-Submissions-To: amiga@uunet.uu.net
  10. X-Post-Discussions-To: comp.sys.amiga.misc
  11.  
  12. Submitted-by: ENG  BENNY <engb@ecf.toronto.edu>
  13. Posting-number: Volume 91, Issue 123
  14. Archive-name: utilities/bmake-0.6/part01
  15.  
  16. [ binaries to appear in comp.binaries.amiga  ...tad ]
  17.  
  18. This program requires Amiga OS 2.0 or higher to run.  Run the program with
  19. the argument `?' to see its usage, or ``-h'' to get more descriptive help
  20. on acceptable command line arguments.
  21.  
  22. Make is a programming utility used to automate the process of recompiling
  23. multiple interdependent source files into an output file, which is called
  24. the goal.  The rules for making the goal are explicitly stated in an input
  25. file called the Makefile, and implicitly determined from builtin inference
  26. rules.  Normally, the Makefile for a goal is written so that the only thing
  27. that needs to be done to recompile newly modified source files is to run
  28. the Make program.
  29.  
  30.  
  31. #!/bin/sh
  32. # This is a shell archive.  Remove anything before this line, then unpack
  33. # it by saving it into a file and typing "sh file".  To overwrite existing
  34. # files, type "sh file -c".  You can also feed this as standard input via
  35. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  36. # will see the following message at the end:
  37. #        "End of archive 1 (of 3)."
  38. # Contents:  Makefile TEST-Makefile ben ben/basename.c ben/makefile
  39. #   ben/scdir.c ben/system.c builtin.c builtins.make compiling
  40. #   depend.c depend.h dumprules.c history include include/scdir.h
  41. #   known-bugs lists.c log.c macro.c main.c make.h param.c parsing.c
  42. #   rawcon.c readme recipe.c snode.c touch.c version.c wishlist
  43. # Wrapped by tadguy@ab20 on Thu Jul  4 12:38:40 1991
  44. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  45. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'Makefile'\"
  47. else
  48. echo shar: Extracting \"'Makefile'\" \(919 characters\)
  49. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  50. X#    Makefile for Make
  51. X#    (c) Copyright 1991 by Ben Eng, All Rights Reserved
  52. X#
  53. X#
  54. X#OPTIONS :=
  55. X#    -DMAXLINE=1024 sets the maximum line length to 1024
  56. X#    -DMAXSUFFIX=16 sets the maximum suffix length to 16
  57. X#    -DMAXPATHNAME=108 sets the maximum length of a path name to 108
  58. X#    -DMAX_MACRONAME=512    to overide internal default of 256
  59. X#    -DFNCALLS=0 to disable function calls
  60. XOPTIONS :=
  61. X#    -gs enables dynamic stack growth
  62. X#    -s enables symbolic information
  63. XCC := dcc
  64. XCFLAGS := -r -ms -proto $(OPTIONS)
  65. XLIBS := -lben
  66. X
  67. XDHOBJS := main.o depend.o input.o dumprules.o make.o builtin.o recipe.o \
  68. X    macro.o expand.o fncall.o read.o
  69. XOBJS = lists.o snode.o param.o touch.o log.o parsing.o $(DHOBJS)
  70. X
  71. XVERS := version.o
  72. X
  73. Xall: bmake
  74. X
  75. Xbmake: $(VERS)
  76. X    $(CC) $(CFLAGS) -o $@ $(OBJS) $(VERS) $(LIBS)
  77. X    -delete make.log
  78. X
  79. X$(VERS): $(OBJS)
  80. X
  81. X$(OBJS): make.h
  82. X
  83. X$(DHOBJS): depend.h
  84. X
  85. Xclean:
  86. X    -delete $(OBJS) $(VERS) make.log
  87. X
  88. Xinstall:
  89. X    copy bmake sys:bin/make
  90. X
  91. END_OF_FILE
  92. if test 919 -ne `wc -c <'Makefile'`; then
  93.     echo shar: \"'Makefile'\" unpacked with wrong size!
  94. fi
  95. # end of 'Makefile'
  96. fi
  97. if test -f 'TEST-Makefile' -a "${1}" != "-c" ; then 
  98.   echo shar: Will not clobber existing file \"'TEST-Makefile'\"
  99. else
  100. echo shar: Extracting \"'TEST-Makefile'\" \(2077 characters\)
  101. sed "s/^X//" >'TEST-Makefile' <<'END_OF_FILE'
  102. X#    Just for testing
  103. X#
  104. X#    To debug, run the resulting make utility with the following arguments
  105. X#        bmake -a -d -n -v9 +l -f TEST-Makefile
  106. X#    the log file make.log will contain a detailed account of what the
  107. X#    program attempted to do.
  108. X#
  109. X
  110. X.jj.k: ; echo "jj to k suffix rule"
  111. X
  112. X.SUFFIXES: .jj .k
  113. X
  114. Xaaaaaa = 1
  115. XA = aaa
  116. XB := $(A)$(A)
  117. XC := $($(B))
  118. X
  119. X#    This one is cool.
  120. XSRCS := $(wildcard #?.c)
  121. XOBJS := $(subst .c,.o,$(SRCS))
  122. XLIBS := -lben
  123. X
  124. X#    Test some of the function calls
  125. XSSRC := $(filter s%,$(SRCS))
  126. XWILD := $(wildcard #?.c)
  127. XBASE := $(basename $(WILD))
  128. XASUF := $(addsuffix .x,$(BASE))
  129. XAPRE := $(addprefix foo-,$(BASE))
  130. XNAPRE := $(words $(APRE))
  131. X
  132. X# test nested conditionals
  133. Xifndef (DOIT)
  134. Xifdef (undefined)
  135. X    undefined := $(strip $(undefined))
  136. Xelse
  137. X    undefined := undefined
  138. Xendif
  139. X    DOIT = $(undefined)
  140. Xendif
  141. X
  142. Xdoodah:
  143. X    @echo "$$ $C $$"
  144. X    @echo "SOURCES:"
  145. X    @echo "$(SRCS)"
  146. X    @echo ""
  147. X    @echo "OBJECTS:"
  148. X    @echo "$(OBJS)"
  149. X    @echo ""
  150. X    @echo "SOURCES starting in s:"
  151. X    @echo "$(SSRC)"
  152. X    @echo ""
  153. X    @echo "replacing ee with EE:"
  154. X    @echo "$(subst ee,EE,feet on the street)"
  155. X    @echo ""
  156. X    @echo "$$(wildcard #?.c)"
  157. X    @echo "$(WILD)"
  158. X    @echo ""
  159. X    @echo "basenames of the above filenames"
  160. X    @echo "$(BASE)"
  161. X    @echo ""
  162. X    @echo "add suffix .x to the above basenames"
  163. X    @echo "$(ASUF)"
  164. X    @echo ""
  165. X    @echo "add prefix foo- to the above basenames"
  166. X    @echo "$(APRE)"
  167. X    @echo "find the first word in the above foo-list"
  168. X    @echo "$(firstword $(APRE))
  169. X    @echo "find the last word in the above foo-list"
  170. X    @echo "$(word $(NAPRE),$(APRE))
  171. X
  172. X#    test a conditional
  173. Xif eq($(DOIT),yes)
  174. X    @echo "DOIT=yes; hurray!"
  175. Xelse
  176. X    @echo "DOIT=$(DOIT)"
  177. Xendif
  178. X
  179. Xfinger := my toe      hurts
  180. Xbleh:
  181. X    echo "$(ugh) $(findstring hello,my hello) $(strip $(finger))"
  182. X
  183. XMONSTER := a.b a.c b.b b.c
  184. XBEES := $(filter %.b,$(MONSTER))
  185. XCEES := $(filter %.c,$(MONSTER))
  186. XNOTB := $(filter-out %.b,$(MONSTER))
  187. XNOTC := $(filter-out %.c,$(MONSTER))
  188. X
  189. X#    Now for a real-live generic rule that will make a.out
  190. X#    from any .c files in your current directory!  Neat huh?
  191. X#    Just change a.out to your favourite file name for the binary.
  192. Xa.out: $(OBJS)
  193. X    $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
  194. END_OF_FILE
  195. if test 2077 -ne `wc -c <'TEST-Makefile'`; then
  196.     echo shar: \"'TEST-Makefile'\" unpacked with wrong size!
  197. fi
  198. # end of 'TEST-Makefile'
  199. fi
  200. if test ! -d 'ben' ; then
  201.     echo shar: Creating directory \"'ben'\"
  202.     mkdir 'ben'
  203. fi
  204. if test -f 'ben/basename.c' -a "${1}" != "-c" ; then 
  205.   echo shar: Will not clobber existing file \"'ben/basename.c'\"
  206. else
  207. echo shar: Extracting \"'ben/basename.c'\" \(352 characters\)
  208. sed "s/^X//" >'ben/basename.c' <<'END_OF_FILE'
  209. X/*    basename.c
  210. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  211. X *
  212. X */
  213. X
  214. X#define AMIGA
  215. X
  216. Xchar *
  217. Xbasename( char *pathname )
  218. X{
  219. X    char *ptr, *filename;
  220. X
  221. X    for( filename = ptr = pathname; *ptr; ptr++ )
  222. X        if( *ptr == '/'        /* directory delimiter */
  223. X#ifdef AMIGA
  224. X            || *ptr == ':'    /* device delimiter */
  225. X#endif
  226. X            ) filename = ptr+1;
  227. X    return( filename );
  228. X}
  229. X
  230. END_OF_FILE
  231. if test 352 -ne `wc -c <'ben/basename.c'`; then
  232.     echo shar: \"'ben/basename.c'\" unpacked with wrong size!
  233. fi
  234. # end of 'ben/basename.c'
  235. fi
  236. if test -f 'ben/makefile' -a "${1}" != "-c" ; then 
  237.   echo shar: Will not clobber existing file \"'ben/makefile'\"
  238. else
  239. echo shar: Extracting \"'ben/makefile'\" \(228 characters\)
  240. sed "s/^X//" >'ben/makefile' <<'END_OF_FILE'
  241. X#    Makefile for ben.lib
  242. X#    (c) Copyright 1991 by Ben Eng, All Rights Reserved
  243. X#
  244. X
  245. XCC = dcc
  246. XAS = dcc
  247. XCFLAGS = -2.0 -ms -r -proto
  248. X
  249. XOBJ = scdir.o basename.o system.o
  250. X
  251. Xben.lib : $(OBJ)
  252. X    join $(OBJ) as $@
  253. X
  254. Xinstall:
  255. X    copy ben.lib dlib:
  256. X
  257. END_OF_FILE
  258. if test 228 -ne `wc -c <'ben/makefile'`; then
  259.     echo shar: \"'ben/makefile'\" unpacked with wrong size!
  260. fi
  261. # end of 'ben/makefile'
  262. fi
  263. if test -f 'ben/scdir.c' -a "${1}" != "-c" ; then 
  264.   echo shar: Will not clobber existing file \"'ben/scdir.c'\"
  265. else
  266. echo shar: Extracting \"'ben/scdir.c'\" \(3381 characters\)
  267. sed "s/^X//" >'ben/scdir.c' <<'END_OF_FILE'
  268. X/*    scan directory for filenames matching wildcard
  269. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  270. X *
  271. X *    scdir() must be called until it returns NULL
  272. X *    or else scdir_abort() must be called to free up resources
  273. X */
  274. X
  275. X#include <exec/types.h>
  276. X#include <exec/execbase.h>
  277. X#include <dos/dos.h>
  278. X#include <dos/dosextens.h>
  279. X#include <dos/dosasl.h>
  280. X#include <clib/dos_protos.h>
  281. X#include <string.h>
  282. X
  283. Xstatic struct AnchorPath AnPath;
  284. Xstatic char *oldwild = NULL;
  285. Xstatic LONG failure = 0;
  286. Xstatic char *result = NULL;
  287. X
  288. X#include <stdlib.h>
  289. X
  290. Xvoid
  291. Xscdir_abort( void )
  292. X{
  293. X    if( result ) {
  294. X        free( result ); result = NULL;
  295. X    }
  296. X    if( oldwild ) {
  297. X        free( oldwild ); oldwild = NULL;
  298. X        if( !failure ) MatchEnd( &AnPath );
  299. X        failure = -1;
  300. X    }
  301. X}
  302. X
  303. X#if 0
  304. X/* uncomment this routine if extern basename() does not return a
  305. X * pointer in the same string as pathname
  306. X */
  307. Xstatic char *
  308. Xbasename( char *pathname )
  309. X{
  310. X    char *ptr, *filename;
  311. X
  312. X    for( filename = ptr = pathname; *ptr; ptr++ )
  313. X        if( *ptr == '/'        /* directory delimiter */
  314. X            || *ptr == ':'    /* device delimiter */
  315. X            ) filename = ptr+1;
  316. X    return( filename );
  317. X}
  318. X#else
  319. Xextern char *basename( char *);
  320. X#endif
  321. X
  322. Xstatic char *
  323. Xscdir_result( char *wild, char *name )
  324. X{
  325. X    long size;
  326. X
  327. X    if( result ) {
  328. X        free( result ); result = NULL;
  329. X    }
  330. X    if( name ) {
  331. X        size = strlen( wild ) + strlen( name ) + 1;
  332. X        if( result = (char *)malloc( size )) {
  333. X            strcpy( result,    wild );
  334. X            strcpy( basename( result ), name );
  335. X            return( result );
  336. X        }
  337. X           MatchEnd( &AnPath );
  338. X    }
  339. X    return( NULL );
  340. X}
  341. X
  342. X/*
  343. X*    NAME
  344. X*        scdir -- scans a directory for filenames matching Amiga wildcard
  345. X*
  346. X*    SYNOPSIS
  347. X*        filename = scdir( wildcard )
  348. X*
  349. X*        char *scdir( const char *scdir )
  350. X*
  351. X*    FUNCTION
  352. X*        This function returns a single filename that matches the AmigaDOS
  353. X*        wildcard.  Consecutive calls with the same wildcard will result
  354. X*        in the next filename that matches the wildcard.  This function
  355. X*        should be called with the same wildcard until all matching
  356. X*        filenames are exhausted, at which time NULL is returned.
  357. X*
  358. X*    INPUTS
  359. X*        wildcard - the full pathname with wildcard to be matched
  360. X*
  361. X*    RESULT
  362. X*
  363. X*        filename - the next filename matching the wildcard or
  364. X*            NULL if there are no more matches found or
  365. X*            NULL if an error occurred
  366. X*
  367. X*   BUGS
  368. X*        Resources are not properly freed if scdir_abort() is never called
  369. X*        or scdir() is not called until a NULL is returned.  That is why
  370. X*        if scdir() is used, the caller should perform an
  371. X*        atexit(scdir_abort), to ensure that resources are always freed.
  372. X*
  373. X*   SEE ALSO
  374. X*        scdir_abort()
  375. X*
  376. X*/
  377. X
  378. Xchar *
  379. Xscdir( const char *wild )
  380. X{
  381. X    int diff = 0;
  382. X
  383. X    if( oldwild ) {
  384. X        diff = strcmp( oldwild, wild );
  385. X        if( !diff && failure ) return( scdir_result( wild,  NULL ));
  386. X    }
  387. X    if( !oldwild || diff ) {
  388. X        if( oldwild ) free( oldwild );
  389. X        oldwild = strdup( wild );
  390. X
  391. X        AnPath.ap_BreakBits = SIGBREAKF_CTRL_C; /* Break on these bits    */
  392. X
  393. X        failure = MatchFirst( wild, &AnPath);
  394. X
  395. X        if( !failure && AnPath.ap_Info.fib_DirEntryType <= 0 ) {
  396. X            return( scdir_result( wild, AnPath.ap_Info.fib_FileName ));
  397. X        }
  398. X    }
  399. X
  400. X    /* same wildcard as before */
  401. X    while( !failure ) {
  402. X        if( failure = MatchNext( &AnPath )) break;
  403. X        if( AnPath.ap_Info.fib_DirEntryType <= 0 ) {
  404. X            return( scdir_result( wild, AnPath.ap_Info.fib_FileName ));
  405. X        }
  406. X    }
  407. X    /* failure */
  408. X    /* This absolutely, positively must be called, all of the time. */
  409. X       MatchEnd( &AnPath );
  410. X    return( scdir_result( wild, NULL ));
  411. X}
  412. X
  413. END_OF_FILE
  414. if test 3381 -ne `wc -c <'ben/scdir.c'`; then
  415.     echo shar: \"'ben/scdir.c'\" unpacked with wrong size!
  416. fi
  417. # end of 'ben/scdir.c'
  418. fi
  419. if test -f 'ben/system.c' -a "${1}" != "-c" ; then 
  420.   echo shar: Will not clobber existing file \"'ben/system.c'\"
  421. else
  422. echo shar: Extracting \"'ben/system.c'\" \(1265 characters\)
  423. sed "s/^X//" >'ben/system.c' <<'END_OF_FILE'
  424. X/*    system.c
  425. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  426. X */
  427. X
  428. X#include <exec/types.h>
  429. X#include <exec/libraries.h>
  430. X#include <dos/dos.h>
  431. X#include <dos/dosextens.h>
  432. X#include <dos/dostags.h>
  433. X
  434. X#include <lib/misc.h>
  435. X#include <clib/exec_protos.h>
  436. X#include <clib/dos_protos.h>
  437. X
  438. X#include <stdio.h>
  439. X#include <stdlib.h>
  440. X
  441. X#define BTOC(bptr,ctype)    ((ctype *)((long)bptr << 2))
  442. X#define CTOB(ptr)           ((long)(ptr) >> 2)
  443. X
  444. X/*    Synchronous external command (wait for return)
  445. X *    Uses your Input/Output unless you supply other handle
  446. X *    Result will be return code of the command, unless the System() call
  447. X *    itself fails, in which case the result will be -1
  448. X */
  449. Xlong
  450. XdoCommand( char *command, BPTR other )
  451. X{
  452. X    struct TagItem stags[3];
  453. X
  454. X    stags[0].ti_Tag = SYS_Input;
  455. X    stags[0].ti_Data = other ? other : Input();
  456. X    stags[1].ti_Tag = SYS_Output;
  457. X    stags[1].ti_Data = other ? 0L : Output();
  458. X    stags[2].ti_Tag = TAG_DONE;
  459. X    return( System( command, stags ));
  460. X}
  461. X
  462. Xlong
  463. Xxsystem( char *cmd )
  464. X{
  465. X    long errcode = -1L;
  466. X    char *s;
  467. X    int sflag = 1;
  468. X
  469. X    if( s = getenv( "SYSTEM" ))
  470. X        sflag = (*s == 'n') ? 0 : 1;
  471. X    
  472. X    if( sflag ) {
  473. X        errcode = doCommand( cmd, 0L );
  474. X    }
  475. X    else {
  476. X        long r;
  477. X        r = Execute( cmd, (BPTR)0L, Output());
  478. X        /* if( r == -1L ) */
  479. X        errcode = IoErr();
  480. X    }
  481. X    return errcode;
  482. X}
  483. END_OF_FILE
  484. if test 1265 -ne `wc -c <'ben/system.c'`; then
  485.     echo shar: \"'ben/system.c'\" unpacked with wrong size!
  486. fi
  487. # end of 'ben/system.c'
  488. fi
  489. if test -f 'builtin.c' -a "${1}" != "-c" ; then 
  490.   echo shar: Will not clobber existing file \"'builtin.c'\"
  491. else
  492. echo shar: Extracting \"'builtin.c'\" \(1855 characters\)
  493. sed "s/^X//" >'builtin.c' <<'END_OF_FILE'
  494. X/*    builtin.c
  495. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  496. X *
  497. X */
  498. X
  499. X#include <fcntl.h>
  500. X#include <clib/exec_protos.h>
  501. X
  502. X#include "make.h"
  503. X#include "depend.h"
  504. X
  505. Xextern void NewList( struct List *);
  506. X
  507. X/*    creates a new BUILTIN rule (of any type)
  508. X *    accepts optional command lines as arguments, ending in a NULL
  509. X *    returns the first target created
  510. X */
  511. Xstatic struct target *
  512. Xnew_targetline( char *tline, ... )
  513. X{
  514. X    va_list argptr;
  515. X    struct List cmdList;
  516. X    struct target *targ;
  517. X    struct command *cmd;
  518. X    char *nextcmd;
  519. X
  520. X    NewList( &cmdList );
  521. X    va_start( argptr, tline );
  522. X    while( nextcmd = va_arg( argptr, char *)) {
  523. X        cmd = new_command( nextcmd );
  524. X        if( !cmd ) break;
  525. X        AddTail( &cmdList, &cmd->node );
  526. X    }
  527. X
  528. X    targ = process_targetline( tline, &cmdList, 1 );
  529. X    if( !targ ) delete_commandlist( &cmdList );
  530. X    va_end( argptr );
  531. X    return( targ );
  532. X}
  533. X
  534. Xint
  535. Xinput_builtins( void )
  536. X{
  537. X    static char *name_list[] = {
  538. X        "builtins.make",
  539. X        "S:builtins.make",
  540. X        NULL
  541. X    };
  542. X    char *filename;
  543. X    int i = 0;
  544. X
  545. X    while( filename = name_list[ i++ ] ) {
  546. X        if( !access( filename, 0 )) { /* file exists */
  547. X            if( input_makefile( filename, 1 )) return( 1 );
  548. X        }
  549. X    }
  550. X    return( 0 );
  551. X}
  552. X
  553. Xint
  554. Xinit_builtins( void )
  555. X{
  556. X    struct target *targ;
  557. X
  558. X    if( Param.no_builtins ) return( 0 );
  559. X
  560. X    set_macro( "CC", "dcc" );
  561. X    set_macro( "AS", "dcc" );
  562. X    set_macro( "CFLAGS", "-proto" );
  563. X
  564. X    targ = new_targetline( ".a:", NULL ); /* no commands for a files */
  565. X    targ = new_targetline( ".c:", NULL ); /* no commands for c files */
  566. X    targ = new_targetline( ".h:", NULL ); /* no commands for c headers */
  567. X    targ = new_targetline( ".i:", NULL ); /* no commands for asm headers */
  568. X
  569. X    targ = new_targetline( ".c.o:", "$(CC) -c $(CFLAGS) -o $@ $<", NULL );
  570. X    targ = new_targetline( ".a.o:", "$(AS) -c $(AFLAGS) -o $@ $<", NULL );
  571. X
  572. X    targ = new_targetline( ".SUFFIXES: .i .h .a .c .o" );
  573. X    
  574. X    if( input_builtins()) return( 1 );
  575. X
  576. X    return( 0 );
  577. X}
  578. X
  579. END_OF_FILE
  580. if test 1855 -ne `wc -c <'builtin.c'`; then
  581.     echo shar: \"'builtin.c'\" unpacked with wrong size!
  582. fi
  583. # end of 'builtin.c'
  584. fi
  585. if test -f 'builtins.make' -a "${1}" != "-c" ; then 
  586.   echo shar: Will not clobber existing file \"'builtins.make'\"
  587. else
  588. echo shar: Extracting \"'builtins.make'\" \(226 characters\)
  589. sed "s/^X//" >'builtins.make' <<'END_OF_FILE'
  590. X#    builtins.make
  591. X#    (c) Copyright 1991 by Ben Eng, All Rights Reserved
  592. X#
  593. X#    example builtins.make file that defines some builtin rules
  594. X
  595. Xclean:
  596. X    echo "clean"
  597. X
  598. Xinstall:
  599. X    echo "install"
  600. X
  601. Xshar:
  602. X    echo "shar"
  603. X
  604. Xlove:
  605. X    @echo "    not war!"
  606. END_OF_FILE
  607. if test 226 -ne `wc -c <'builtins.make'`; then
  608.     echo shar: \"'builtins.make'\" unpacked with wrong size!
  609. fi
  610. # end of 'builtins.make'
  611. fi
  612. if test -f 'compiling' -a "${1}" != "-c" ; then 
  613.   echo shar: Will not clobber existing file \"'compiling'\"
  614. else
  615. echo shar: Extracting \"'compiling'\" \(3099 characters\)
  616. sed "s/^X//" >'compiling' <<'END_OF_FILE'
  617. X
  618. X                       Documentation for Compiling
  619. X                       Copyright (c) 1991 by Ben Eng
  620. X
  621. X
  622. XHOW TO MAKE
  623. X
  624. XThe source code for this program was written for the DICE C compiler,
  625. Xversion 2.06.22, by Matthew Dillon.  The tab size is set to 4.  You will
  626. Xrequire the 2.0 Amiga include files from CATS of Commodore-Amiga to compile
  627. Xthis program.  The source code should compile under any ANSI C compiler for
  628. Xthe Amiga, but I wouldn't bet on it.
  629. X
  630. XIf the executable, ``bmake'', needs to be recompiled then the following
  631. Xprocedure should be used.
  632. X
  633. XFirst, the ``include/scdir.h'' header file should be copied to a directory
  634. Xin the include path for your compiler.  The compiler should be set up to
  635. Xcompile using the Amiga OS 2.0 (or later) include files.
  636. X
  637. XThe link library ``ben.lib'' needs to be made first.  Change your directory
  638. Xto the ``ben'' directory and type ``make'' (or ``bmake'' if that is
  639. Xavailable to you).  If all goes well, then the ``ben.lib'' library will be
  640. Xcreated; it should be moved to the library search path for your compiler,
  641. Xso that the linker will be able to find it.
  642. X
  643. XChange your directory to the main source directory for the make utility and
  644. Xtype ``make'' or ``bmake'' to create the binary executable file ``bmake''.
  645. XThis file can be renamed to the standard ``make'', and placed in the
  646. Xcommand search path for convenience.
  647. X
  648. X
  649. XPARAMETERS
  650. X
  651. XFNCALLS = (1 default) non-zero if function calls are activated
  652. X
  653. X    If function calls are recognized, this parameter should be defined
  654. X    to be non-zero.  Disabling function calls will make the executable
  655. X    somewhat smaller, and memory requirements will be lower.
  656. X
  657. XMAXLINE = (1024 default) the maximum number of characters allowed per line
  658. X
  659. X    This parameter limits the maximum size of a line that can be read from
  660. X    a Makefile, the maximum size of a line that can be assigned to a
  661. X    variable, and the maximum size of a macro expansion.  Effectively,
  662. X    MAXLINE is the upper limit on anything manipulated by the Make program.
  663. X    Lines of this size are declared in static storage (input.c) and
  664. X    dynamically (macro.c, etc.).
  665. X
  666. XMAXSUFFIX = (16 default) the maximum number of characters in a suffix
  667. X
  668. X    This parameter limits the maximum size of filename extensions
  669. X    recognized by the Make program.  This affects suffix rules and other
  670. X    operations that operating on suffixes.  Suffixes are allocated on
  671. X    the stack and dynamically in this fixed size.
  672. X
  673. XMAX_MACRONAME = (256 default) the maximum number of characters in a name
  674. X
  675. X    This parameter limits the size of a macro name.
  676. X
  677. XMAXPATHNAME    = (108 default) the maximum number of characters in a pathname
  678. X
  679. X    This parameter limits the size of a pathname that can be used to
  680. X    resolve suffix rules.  Dynamically allocated.
  681. X
  682. X
  683. XOPTIONS
  684. X
  685. XIn the Makefile, the -gs option can added to CFLAGS to enable DICE's
  686. Xdynamic stack code.  It makes the program grow in size by a couple of
  687. Xkilobytes, and it slows down execution by a few milliseconds, but it does
  688. Xmake it safe to run the Make program on a huge Makefile that makes
  689. Xextensive use of recursive macros and rules, without having to worry about
  690. Xoverflowing the stack.
  691. X
  692. END_OF_FILE
  693. if test 3099 -ne `wc -c <'compiling'`; then
  694.     echo shar: \"'compiling'\" unpacked with wrong size!
  695. fi
  696. # end of 'compiling'
  697. fi
  698. if test -f 'depend.c' -a "${1}" != "-c" ; then 
  699.   echo shar: Will not clobber existing file \"'depend.c'\"
  700. else
  701. echo shar: Extracting \"'depend.c'\" \(3984 characters\)
  702. sed "s/^X//" >'depend.c' <<'END_OF_FILE'
  703. X/*    depend.c
  704. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  705. X *
  706. X */
  707. X
  708. X#include <clib/exec_protos.h>
  709. X
  710. X#include "make.h"
  711. X#include "depend.h"
  712. X
  713. Xstruct target *
  714. Xfind_target( char *targetname )
  715. X{
  716. X    struct target *targ = NULL;
  717. X
  718. X    for( struct target *ln = Global.targetlist.lh_Head; ln->node.ln_Succ;
  719. X        ln = ln->node.ln_Succ ) {
  720. X        if( !strcmp( targetname, ln->name )) {
  721. X            targ = ln;
  722. X            break;
  723. X        }
  724. X    }
  725. X
  726. X    return( targ );
  727. X}
  728. X
  729. Xstruct target *
  730. Xnew_target( char *targetname )
  731. X{
  732. X    long size;
  733. X    struct target *new = NULL;
  734. X
  735. X    if( targetname && *targetname && !( new = find_target( targetname ))) {
  736. X        size = sizeof(struct target) + strlen( targetname );
  737. X        new = (struct target *)malloc( size );
  738. X        if( new ) {
  739. X            NewList( &new->dependlist );
  740. X            NewList( &new->commandlist );
  741. X            new->alternate = NULL;
  742. X            new->mtime = 0L;
  743. X            new->flags = 0L;
  744. X            if( targetname ) strcpy( new->name, targetname );
  745. X            else *targetname = (char)0;
  746. X        }
  747. X    }
  748. X    return( new );
  749. X}
  750. X
  751. Xint
  752. Xdelete_target( struct target *targ )
  753. X{
  754. X    free( targ );
  755. X    return( 0 );
  756. X}
  757. X
  758. Xvoid
  759. Xdelete_targetlist( struct List *list )
  760. X{
  761. X    for_list( list, delete_target );
  762. X    NewList( list );
  763. X}
  764. X
  765. Xstruct depend *
  766. Xnew_depend( char *dependname )
  767. X{
  768. X    struct depend *new = NULL;
  769. X    long size;
  770. X
  771. X    if( dependname ) {
  772. X        size = sizeof(struct depend) + strlen( dependname );
  773. X        if( new = (struct depend *)malloc( size )) {
  774. X            strcpy( new->name, dependname );
  775. X        }
  776. X    }
  777. X    return( new );
  778. X}
  779. X
  780. Xint
  781. Xdelete_depend( struct depend *dep )
  782. X{
  783. X    free( dep );
  784. X    return( 0 );
  785. X}
  786. X
  787. Xvoid
  788. Xdelete_dependlist( struct List *list )
  789. X{
  790. X    for_list( list, delete_depend );
  791. X    NewList( list );
  792. X}
  793. X
  794. Xstruct command *
  795. Xnew_command( char *cmd )
  796. X{
  797. X    long size;
  798. X    struct command *new = NULL;
  799. X    if( cmd && *cmd ) {
  800. X        size = sizeof(struct command) + strlen( cmd );
  801. X        new = (struct command *)malloc( size );
  802. X        if( new ) {
  803. X            if( *cmd == '-' ) {
  804. X                new->flags = CF_IGNORE;
  805. X                cmd++;
  806. X            }
  807. X            else if( *cmd == '@' ) {
  808. X                new->flags = CF_NOECHO;
  809. X                cmd++;
  810. X            }
  811. X            else new->flags = 0;
  812. X            strcpy( new->cmd, cmd );
  813. X        }
  814. X    }
  815. X    return( new );
  816. X}
  817. X
  818. Xint
  819. Xdelete_command( struct command *cmd )
  820. X{
  821. X    free( cmd );
  822. X    return( 0 );
  823. X}
  824. X
  825. Xvoid
  826. Xdelete_commandlist( struct List *list )
  827. X{
  828. X    for_list( list, delete_command );
  829. X    NewList( list );
  830. X}
  831. X
  832. Xstruct suffixrule *
  833. Xfind_suffixrule( char *dep_suf, char *tar_suf )
  834. X{
  835. X    struct suffixrule *sr = NULL;
  836. X
  837. X    for( struct suffixrule *ln = Global.suffixlist.lh_Head; ln->node.ln_Succ;
  838. X        ln = ln->node.ln_Succ ) {
  839. X        if( !strcmp( dep_suf, ln->dep_suf ) &&
  840. X            !strcmp( tar_suf, ln->tar_suf )) {
  841. X            sr = ln;
  842. X            break;
  843. X        }
  844. X    }
  845. X
  846. X    return( sr );
  847. X}
  848. X
  849. Xstruct suffixrule *
  850. Xnew_suffixrule( char *dep_suf, char *tar_suf )
  851. X{
  852. X    int found_flag = 0;
  853. X    long size = sizeof(struct suffixrule);
  854. X    struct suffixrule *new = find_suffixrule( dep_suf, tar_suf );
  855. X    if( new ) found_flag = 1;
  856. X    else new = (struct suffixrule *)malloc( size );
  857. X
  858. X    if( new ) {
  859. X        strcpy( new->tar_suf, tar_suf );
  860. X        strcpy( new->dep_suf, dep_suf );
  861. X        if( !found_flag ) AddTail( &Global.suffixlist, &new->node );
  862. X    }
  863. X    return( new );
  864. X}
  865. X
  866. Xint
  867. Xdelete_suffixrule( struct suffixrule *rule )
  868. X{
  869. X    free( rule );
  870. X    return( 0 );
  871. X}
  872. X
  873. Xvoid
  874. Xdelete_suffixlist( struct List *list )
  875. X{
  876. X    for_list( list, delete_suffixrule );
  877. X}
  878. X
  879. Xstruct target *
  880. Xadd_suffix_targets( char *suf )
  881. X{
  882. X    char *next, tar_suf[ 16 ], dep_suf[ 16 ];    
  883. X    struct target *ln, *first_targ = NULL;
  884. X
  885. X    for( ln = (struct target *)Global.targetlist.lh_Head;
  886. X        ln->node.ln_Succ; ln = ln->node.ln_Succ ) {
  887. X
  888. X        next = ln->name;
  889. X        *dep_suf = *tar_suf = (char)0;
  890. X
  891. X        if( *next++ == '.' ) {
  892. X            next = parse_strtok( tar_suf, next, sizeof(suf)-1, isnotsuf );
  893. X            if( *next++ == '.' ) {
  894. X                strcpy( dep_suf, tar_suf ); /* double-suffix */
  895. X                next = parse_strtok( tar_suf, next, sizeof(suf)-1, isnotsuf );
  896. X            }
  897. X        }
  898. X        if( !strcmp( suf, dep_suf) || !strcmp( suf, tar_suf )) {
  899. X            /* transform a target rule into a suffix rule */
  900. X            struct suffixrule *sr = new_suffixrule( dep_suf, tar_suf );
  901. X            if( sr ) {
  902. X                sr->targ = ln;
  903. X                ln->flags |= TF_SUFFIX;
  904. X                if( !first_targ ) first_targ = ln;
  905. X            }
  906. X            else return( NULL ); /* error */
  907. X        }
  908. X    }
  909. X
  910. X    return( first_targ );
  911. X}
  912. END_OF_FILE
  913. if test 3984 -ne `wc -c <'depend.c'`; then
  914.     echo shar: \"'depend.c'\" unpacked with wrong size!
  915. fi
  916. # end of 'depend.c'
  917. fi
  918. if test -f 'depend.h' -a "${1}" != "-c" ; then 
  919.   echo shar: Will not clobber existing file \"'depend.h'\"
  920. else
  921. echo shar: Extracting \"'depend.h'\" \(2635 characters\)
  922. sed "s/^X//" >'depend.h' <<'END_OF_FILE'
  923. X/*    depend.h
  924. X *
  925. X */
  926. X
  927. X#include <time.h>
  928. X
  929. X#ifndef MAXLINE
  930. X#define MAXLINE 1024
  931. X#endif
  932. X
  933. X#ifndef MAXSUFFIX
  934. X#define MAXSUFFIX 16
  935. X#endif
  936. X
  937. X#ifndef MAX_MACRONAME
  938. X#define MAX_MACRONAME 256
  939. X#endif
  940. X
  941. X#ifndef FNCALLS
  942. X#define FNCALLS 1
  943. X#endif
  944. X
  945. Xstruct target {
  946. X    struct Node node;
  947. X    struct List dependlist;
  948. X    struct List commandlist;
  949. X    struct List *alternate; /* if not OWNER of the commandlist */
  950. X    time_t mtime;
  951. X    long flags;
  952. X    int line_number;
  953. X    char name[ 2 ];
  954. X};
  955. X
  956. X/* target flags */
  957. X#define TF_ADDED    0x00000001
  958. X#define TF_OWNER    0x00000002
  959. X#define TF_SUFFIX    0x00000004
  960. X#define TF_BUILTIN    0x00000008
  961. X#define TF_MADE        0x80000000
  962. X
  963. Xstruct depend {
  964. X    struct Node node;
  965. X    char name[ 2 ];
  966. X};
  967. X
  968. Xstruct command {
  969. X    struct Node node;
  970. X    long flags;
  971. X    char cmd[ 2 ];
  972. X};
  973. X
  974. X#define CF_IGNORE    0x00000001
  975. X#define CF_NOECHO    0x00000002
  976. X
  977. Xstruct suffixrule {
  978. X    struct Node node;
  979. X    char tar_suf[ MAXSUFFIX ];
  980. X    char dep_suf[ MAXSUFFIX ];
  981. X    struct target *targ;
  982. X};
  983. X
  984. Xstruct macro {
  985. X    struct Node node;
  986. X    long flags;
  987. X    char *name;    /* dynamic */
  988. X    char *expansion; /* dynamic */
  989. X};
  990. X
  991. Xstruct fncall {
  992. X    char *name;
  993. X    int (*call)(struct macro *, char *);
  994. X};
  995. X
  996. X/* macro flags */
  997. X#define MF_EXPANDED    0x00000001
  998. X#define MF_SIMPLE    0x00000002
  999. X#define MF_ADDED    0x80000000
  1000. X
  1001. Xint getline( char *buf, int sz, FILE *in );
  1002. X
  1003. Xstruct target *find_target( char *targetname );
  1004. Xstruct target *new_target( char *targetname );
  1005. Xint delete_target( struct target *targ );
  1006. Xvoid delete_targetlist( struct List *list );
  1007. X
  1008. Xstruct depend *new_depend( char *dependname );
  1009. Xint delete_depend( struct depend *dep );
  1010. Xvoid delete_dependlist( struct List *list );
  1011. X
  1012. Xstruct command *new_command( char *cmd );
  1013. Xint delete_command( struct command *cmd );
  1014. Xvoid delete_commandlist( struct List *list );
  1015. X
  1016. Xstruct suffixrule *new_suffixrule( char *dep_suf, char *tar_suf );
  1017. Xint delete_suffixrule( struct suffixrule *rule );
  1018. Xvoid delete_suffixlist( struct List *list );
  1019. Xstruct target *add_suffix_targets( char *suf );
  1020. X
  1021. Xstruct target *find_macro( char *macroname );
  1022. Xstruct macro *new_macro( char *name, char *expansion );
  1023. Xstruct macro *set_macro( char *name, char *expansion );
  1024. Xvoid set_target_macros( char *tarname, char *depname );
  1025. Xint delete_macro( struct macro *mac );
  1026. Xvoid delete_macrolist( struct List *list );
  1027. X
  1028. Xstruct fncall *find_fncall( char *name );
  1029. Xvoid shift_string_left( char *string, int shift );
  1030. Xint expand_macros( char *dest, char *src, int maxlen );
  1031. X
  1032. Xvoid dump_all( void );
  1033. X
  1034. Xstruct target *process_targetline( char *line, struct List *cmdlist,
  1035. X    int bulitin_flag );
  1036. Xstruct macro *process_macroline( char *line );
  1037. X
  1038. Xtime_t nowtime( void );
  1039. Xvoid touch( const char *filename );
  1040. X
  1041. Xint recipe( const char *goalname, struct List *cmdlist );
  1042. END_OF_FILE
  1043. if test 2635 -ne `wc -c <'depend.h'`; then
  1044.     echo shar: \"'depend.h'\" unpacked with wrong size!
  1045. fi
  1046. # end of 'depend.h'
  1047. fi
  1048. if test -f 'dumprules.c' -a "${1}" != "-c" ; then 
  1049.   echo shar: Will not clobber existing file \"'dumprules.c'\"
  1050. else
  1051. echo shar: Extracting \"'dumprules.c'\" \(1933 characters\)
  1052. sed "s/^X//" >'dumprules.c' <<'END_OF_FILE'
  1053. X/*    dumprules.c
  1054. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1055. X *
  1056. X */
  1057. X
  1058. X#include "make.h"
  1059. X#include "depend.h"
  1060. X
  1061. X
  1062. Xvoid
  1063. Xdump_macros( struct List *mlist )
  1064. X{
  1065. X    struct macro *mac;
  1066. X
  1067. X    debugprintf( 2,( "** Macros **\n" ));
  1068. X
  1069. X    for( mac = mlist->lh_Head; mac->node.ln_Succ; mac =
  1070. X        mac->node.ln_Succ ) {
  1071. X        logprintf( "%s %s %s\n", mac->name,
  1072. X            (mac->flags & MF_SIMPLE) ? ":=" : "=", mac->expansion );
  1073. X    }
  1074. X    logprintf( "\n" );
  1075. X}
  1076. X
  1077. Xstatic void
  1078. Xdump_dependencies( struct List *dlist )
  1079. X{
  1080. X    struct depend *dep;
  1081. X
  1082. X    for( dep = dlist->lh_Head; dep->node.ln_Succ; dep =
  1083. X        dep->node.ln_Succ ) {
  1084. X        logprintf( " %s", dep->name );
  1085. X    }
  1086. X    logprintf( "\n" );
  1087. X}
  1088. X
  1089. Xstatic void
  1090. Xdump_commands( struct List *clist )
  1091. X{
  1092. X    struct command *cmd;
  1093. X
  1094. X    for( cmd = clist->lh_Head; cmd->node.ln_Succ; cmd =
  1095. X        cmd->node.ln_Succ ) {
  1096. X        logprintf( "\t%s\n", cmd->cmd );
  1097. X    }
  1098. X}
  1099. X
  1100. Xvoid
  1101. Xdump_targets( struct List *tlist )
  1102. X{
  1103. X    struct target *targ;
  1104. X
  1105. X    debugprintf( 2, ( "** Target Rules **\n" ));
  1106. X
  1107. X    for( targ = tlist->lh_Head; targ->node.ln_Succ; targ =
  1108. X        targ->node.ln_Succ ) {
  1109. X        logprintf( "\n%s", targ->name );
  1110. X        if( targ->flags & TF_SUFFIX ) logprintf( " [SUFFIX]" );
  1111. X        if( targ->flags & TF_BUILTIN ) logprintf( " [BUILTIN]" );
  1112. X        logprintf( ":" );
  1113. X        dump_dependencies( &targ->dependlist );
  1114. X        if( targ->flags & TF_OWNER )
  1115. X            dump_commands( &targ->commandlist );
  1116. X        else
  1117. X            dump_commands( targ->alternate );
  1118. X    }
  1119. X}
  1120. X
  1121. Xvoid
  1122. Xdump_suffixrules( struct List *slist )
  1123. X{
  1124. X    struct suffixrule *sr;
  1125. X
  1126. X    debugprintf( 2, ( "** Suffix Rules **\n" ));
  1127. X
  1128. X    for( sr = slist->lh_Head; sr->node.ln_Succ; sr =
  1129. X        sr->node.ln_Succ ) {
  1130. X        logprintf( "\n.%s.%s :\n", sr->dep_suf, sr->tar_suf );
  1131. X        if( sr->targ->flags & TF_OWNER )
  1132. X            dump_commands( &sr->targ->commandlist );
  1133. X        else
  1134. X            dump_commands( sr->targ->alternate );
  1135. X    }
  1136. X}
  1137. X
  1138. X
  1139. Xvoid
  1140. Xdump_all( void )
  1141. X{
  1142. X    debugprintf( 2, ("\n** Debug output for rules ** \n" ));
  1143. X    dump_macros( &Global.macrolist );
  1144. X    dump_suffixrules( &Global.suffixlist );
  1145. X    dump_targets( &Global.targetlist );    
  1146. X}
  1147. END_OF_FILE
  1148. if test 1933 -ne `wc -c <'dumprules.c'`; then
  1149.     echo shar: \"'dumprules.c'\" unpacked with wrong size!
  1150. fi
  1151. # end of 'dumprules.c'
  1152. fi
  1153. if test -f 'history' -a "${1}" != "-c" ; then 
  1154.   echo shar: Will not clobber existing file \"'history'\"
  1155. else
  1156. echo shar: Extracting \"'history'\" \(2923 characters\)
  1157. sed "s/^X//" >'history' <<'END_OF_FILE'
  1158. X
  1159. X                     HISTORY of CHANGES to the Make program
  1160. X                          Copyright (c) 1991 by Ben Eng
  1161. X
  1162. XKEY:
  1163. X    -N    New Feature
  1164. X    -B    Bug Fix in program
  1165. X    -D    Documentation
  1166. X
  1167. X---
  1168. XJune 2, 1991
  1169. X
  1170. Xchanges from 0.5 to 0.6
  1171. X
  1172. X    -B    macro expansion in the arguments to eq() and neq() conditions
  1173. X    -B    removed rawcon.c, so ^C breaks should work better
  1174. X
  1175. X    -N    added $(words text) function call
  1176. X    -N    added $(word n,text) function call
  1177. X    -N    added $(firstword text) function call
  1178. X    -N    added stubs for function calls that are not implemented
  1179. X
  1180. X    -N    changed static storage to dynamic storage for reading the Makefile
  1181. X    -N    the maximum line length can now be set as a parameter
  1182. X    -N    function calls are now able to accept arguments up to MaxLine
  1183. X        in length
  1184. X    -N    added ``pragma'' directive to specify command line arguments
  1185. X        for the Make program within the Makefile
  1186. X
  1187. X    -B    removed enforcer hits; all were read-hits :-).
  1188. X
  1189. X---
  1190. XMay 31, 1991
  1191. X
  1192. Xchanges from 0.4 to 0.5
  1193. X
  1194. X    -N    conditionals
  1195. X    -B    command line macro assignments are performed twice; once before
  1196. X        Makefile is read, and once before the Makefile is run
  1197. X
  1198. X---
  1199. XMay 30, 1991
  1200. X
  1201. Xchanges from 0.3 to 0.4
  1202. X
  1203. X    -B    allow commas to be escaped with a backslash in function calls
  1204. X    -B    $(subst) changed to work with in any position; not just suffixes
  1205. X
  1206. X    -N    added $(filter pattern,text) function call
  1207. X    -N    added $(filter-out pattern,text) function call
  1208. X    -N    added $(wildcard pattern) function call
  1209. X    -N    added $(basename names) function call
  1210. X    -N    added $(addsuffix suffix,names) function call
  1211. X    -N    added $(addprefix prefix,names) function call
  1212. X
  1213. X
  1214. X---
  1215. XMay 29, 1991    distributed 0.3 on ab20.larc.nasa.gov [128.155.23.64]
  1216. X
  1217. Xchanges from 0.2 to 0.3
  1218. X
  1219. X    -D    fixed the previous dates in the HISTORY file
  1220. X    -D    fixed the documentation on simple variables
  1221. X
  1222. X    -B    added better error detection for infinitely
  1223. X        expanded macros.
  1224. X
  1225. X    -B    fixed the macro expansion for variables that expand
  1226. X        to a value containing the character `$'
  1227. X
  1228. X    -B    fixed the macro expansion for unknown variables
  1229. X
  1230. X    -N    added function call capabilities to the macro
  1231. X                    expansion facility
  1232. X    -N    added $(strip string) function call
  1233. X    -N    added $(findstring find,in) function call
  1234. X    -N    added $(subst from,to,text) function call
  1235. X
  1236. X
  1237. X---
  1238. XMay 28, 1991    distributed 0.2 on Bix
  1239. X
  1240. Xchanges from 0.1 to 0.2
  1241. X
  1242. X    -B    added a check for out of memory in ben/scdir.c
  1243. X
  1244. X    -N    parsing of command line macro=value definitions
  1245. X
  1246. X---
  1247. XMay 27, 1991    distributed 0.1 on Tardis BBS
  1248. X
  1249. Xchanges from 0.0 to 0.1
  1250. X
  1251. X    -N    recursive macro expansions within variable name
  1252. X        references are now supported; ie. ${hello$(idx)}.
  1253. X
  1254. X    -B    multiple expansions of the same variable was
  1255. X        incorrectly trapped as an infinitely recursive
  1256. X        macro expansion.
  1257. X
  1258. X    -B    standard rules are now allowed to be defined as
  1259. X        builtin rules, without being selected as the
  1260. X        default target (goal) to be made.
  1261. X
  1262. X    -B    when the Makefile does not end in an empty line
  1263. X        the last rule is thrown out.
  1264. X
  1265. X---
  1266. XMay 26, 1991    limited local distribution
  1267. X
  1268. Xinitial release 0.0
  1269. X
  1270. X---
  1271. END_OF_FILE
  1272. if test 2923 -ne `wc -c <'history'`; then
  1273.     echo shar: \"'history'\" unpacked with wrong size!
  1274. fi
  1275. # end of 'history'
  1276. fi
  1277. if test ! -d 'include' ; then
  1278.     echo shar: Creating directory \"'include'\"
  1279.     mkdir 'include'
  1280. fi
  1281. if test -f 'include/scdir.h' -a "${1}" != "-c" ; then 
  1282.   echo shar: Will not clobber existing file \"'include/scdir.h'\"
  1283. else
  1284. echo shar: Extracting \"'include/scdir.h'\" \(161 characters\)
  1285. sed "s/^X//" >'include/scdir.h' <<'END_OF_FILE'
  1286. X/*    scdir.h
  1287. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1288. X */
  1289. X
  1290. Xvoid scdir_abort( void );    /* atexit( scdir_abort ); */
  1291. Xchar *scdir( const char * wild );
  1292. X
  1293. END_OF_FILE
  1294. if test 161 -ne `wc -c <'include/scdir.h'`; then
  1295.     echo shar: \"'include/scdir.h'\" unpacked with wrong size!
  1296. fi
  1297. # end of 'include/scdir.h'
  1298. fi
  1299. if test -f 'known-bugs' -a "${1}" != "-c" ; then 
  1300.   echo shar: Will not clobber existing file \"'known-bugs'\"
  1301. else
  1302. echo shar: Extracting \"'known-bugs'\" \(739 characters\)
  1303. sed "s/^X//" >'known-bugs' <<'END_OF_FILE'
  1304. X
  1305. XJune 2, 1991
  1306. X
  1307. X--
  1308. XUsing the backslash character as a character escape
  1309. X
  1310. XExample:    $(fncall \,arg1, ... )
  1311. XExample:    echo "price = \$100"
  1312. X
  1313. XAvoid using the backslash to escape characters.  I haven't any clue what
  1314. Xthe backslash will generally do, but in particular places the backslash can
  1315. Xbe used to escape the meaning of the next character.  Although that
  1316. Xprobably works fine in the particular context, the escaped character is not
  1317. Xbe remapped properly to the character itself, so the backslash character
  1318. Xwill hang around, as if it were literal.  $$ should be used instead of \$.
  1319. X
  1320. X--
  1321. XA function call that returns an ERROR will not cause the Makefile to be
  1322. Xaborted.  Execution will continue as if the function call returned an
  1323. Xempty string.
  1324. X
  1325. X--
  1326. END_OF_FILE
  1327. if test 739 -ne `wc -c <'known-bugs'`; then
  1328.     echo shar: \"'known-bugs'\" unpacked with wrong size!
  1329. fi
  1330. # end of 'known-bugs'
  1331. fi
  1332. if test -f 'lists.c' -a "${1}" != "-c" ; then 
  1333.   echo shar: Will not clobber existing file \"'lists.c'\"
  1334. else
  1335. echo shar: Extracting \"'lists.c'\" \(503 characters\)
  1336. sed "s/^X//" >'lists.c' <<'END_OF_FILE'
  1337. X/*    lists.c
  1338. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1339. X *
  1340. X */
  1341. X
  1342. X#include <clib/exec_protos.h>
  1343. X
  1344. X#include "make.h"
  1345. X
  1346. X
  1347. Xstruct void *
  1348. Xfor_list( struct List *list, long (*node_fn)(void *))
  1349. X{
  1350. X    struct Node *ln, *succ;
  1351. X
  1352. X    for( ln = list->lh_Head; ln->ln_Succ; ln = succ ) {
  1353. X        succ = ln->ln_Succ;
  1354. X        if( (*node_fn)( ln )) return( ln );
  1355. X    }
  1356. X    return( NULL );
  1357. X}
  1358. X
  1359. Xvoid
  1360. Xattach_list( struct List *newlist, struct List *oldlist )
  1361. X{
  1362. X    struct Node *ln;
  1363. X
  1364. X    while( ln = RemHead( oldlist ))
  1365. X        AddTail( newlist, ln );
  1366. X}
  1367. X
  1368. END_OF_FILE
  1369. if test 503 -ne `wc -c <'lists.c'`; then
  1370.     echo shar: \"'lists.c'\" unpacked with wrong size!
  1371. fi
  1372. # end of 'lists.c'
  1373. fi
  1374. if test -f 'log.c' -a "${1}" != "-c" ; then 
  1375.   echo shar: Will not clobber existing file \"'log.c'\"
  1376. else
  1377. echo shar: Extracting \"'log.c'\" \(894 characters\)
  1378. sed "s/^X//" >'log.c' <<'END_OF_FILE'
  1379. X/*    log.c
  1380. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1381. X *
  1382. X */
  1383. X
  1384. X#include "make.h"
  1385. X
  1386. X#define LOGFILE "make.log"
  1387. X
  1388. Xint
  1389. Xopen_logfile( void )
  1390. X{
  1391. X    if( !Global.logfile ) {
  1392. X        Global.logfile = fopen( LOGFILE, "a" );
  1393. X        if( !Global.logfile ) return( 1 );
  1394. X    }
  1395. X    return( 0 );
  1396. X}
  1397. X
  1398. Xvoid
  1399. Xclose_logfile( void )
  1400. X{
  1401. X    if( Global.logfile ) fclose( Global.logfile );
  1402. X}
  1403. X
  1404. Xvoid
  1405. Xlogfile( char *string )
  1406. X{
  1407. X    FILE *out;
  1408. X
  1409. X    if( Param.log && !Global.logfile ) open_logfile();
  1410. X
  1411. X    out = ( Param.log ) ? Global.logfile : stdout;
  1412. X    if( Param.log || Param.verbosity ) {
  1413. X        fputs( string, out );
  1414. X        fputc( '\n', out );
  1415. X        fflush( out );
  1416. X    }
  1417. X}
  1418. X
  1419. Xvoid
  1420. Xlogprintf( const char *fmt, ... )
  1421. X{
  1422. X    va_list argptr;
  1423. X    FILE *out;
  1424. X
  1425. X    va_start( argptr, fmt );
  1426. X    if( Param.log && !Global.logfile ) open_logfile();
  1427. X
  1428. X    out = ( Param.log ) ? Global.logfile : stdout;
  1429. X    if( Param.log || Param.verbosity ) {
  1430. X        vfprintf( out, fmt, argptr );
  1431. X    }
  1432. X    va_end( argptr );
  1433. X}
  1434. END_OF_FILE
  1435. if test 894 -ne `wc -c <'log.c'`; then
  1436.     echo shar: \"'log.c'\" unpacked with wrong size!
  1437. fi
  1438. # end of 'log.c'
  1439. fi
  1440. if test -f 'macro.c' -a "${1}" != "-c" ; then 
  1441.   echo shar: Will not clobber existing file \"'macro.c'\"
  1442. else
  1443. echo shar: Extracting \"'macro.c'\" \(3534 characters\)
  1444. sed "s/^X//" >'macro.c' <<'END_OF_FILE'
  1445. X/*    macro.c
  1446. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1447. X *
  1448. X *    USER DEFINABLE variables
  1449. X *
  1450. X *    $x        = the variable x
  1451. X *    $(var)    = the variable var
  1452. X *    ${var}    = the same variable var
  1453. X *
  1454. X *    INTERNAL AUTOMATIC variables (not for user definitions)
  1455. X *
  1456. X *    $$ = $
  1457. X *    $@ = target filename
  1458. X *    $* = basename of target
  1459. X *    $< = dependent filename
  1460. X *    $^ = all dependents of target newer than target (not-imp)
  1461. X *    $% = dependent member of the target archive (not-imp)
  1462. X *    $? = all dependents of the target archive (not-imp)
  1463. X */
  1464. X
  1465. X#include <clib/exec_protos.h>
  1466. X
  1467. X#include "make.h"
  1468. X#include "depend.h"
  1469. X
  1470. X/*    internal function used to find an existing variable */
  1471. Xstruct target *
  1472. Xfind_macro( char *macroname )
  1473. X{
  1474. X    struct macro *mac = NULL;
  1475. X
  1476. X    for( struct macro *ln = Global.macrolist.lh_Head; ln->node.ln_Succ;
  1477. X        ln = ln->node.ln_Succ ) {
  1478. X        if( !strcmp( macroname, ln->name )) {
  1479. X            mac = ln;
  1480. X            break;
  1481. X        }
  1482. X    }
  1483. X
  1484. X    return( mac );
  1485. X}
  1486. X
  1487. X/*    internal allocation function */
  1488. Xstruct macro *
  1489. Xnew_macro( char *name, char *expansion )
  1490. X{
  1491. X    long size = sizeof(struct macro);
  1492. X    struct macro *new = (struct macro *)calloc( size, 1 );
  1493. X    if( new ) {
  1494. X        if( name )
  1495. X            if( !(new->name = strdup( name ))) goto death;
  1496. X        if( expansion )
  1497. X            if( !(new->expansion = strdup( expansion ))) goto death;
  1498. X        new->flags = 0;
  1499. X    }
  1500. X    return( new );
  1501. Xdeath:
  1502. X    if( new ) {
  1503. X        if( new->name ) free( new->name );
  1504. X        if( new->expansion ) free( new->expansion );
  1505. X        free( new );
  1506. X    }
  1507. X    return( NULL );
  1508. X}
  1509. X
  1510. X/*    internal deallocation function */
  1511. Xint
  1512. Xdelete_macro( struct macro *mac )
  1513. X{
  1514. X    if( mac->name ) free( mac->name );
  1515. X    if( mac->expansion ) free( mac->expansion );
  1516. X    free( mac );
  1517. X    return( 0 );
  1518. X}
  1519. X
  1520. X/*    perform a variable assignment
  1521. X *    this is the entry point from outside
  1522. X *    a NULL or null string will delete the variable
  1523. X */
  1524. Xstruct macro *
  1525. Xset_macro( char *name, char *expansion )
  1526. X{
  1527. X    struct macro *mac = NULL;
  1528. X    int create_flag = (expansion && !isemptyline( expansion ));
  1529. X
  1530. X    if( mac = find_macro( name )) {
  1531. X        if( create_flag ) {
  1532. X            if( mac->expansion ) free( mac->expansion );
  1533. X            mac->expansion = strdup( expansion );
  1534. X        }
  1535. X        else {
  1536. X            Remove( &mac->node );
  1537. X            delete_macro( mac );
  1538. X            mac = NULL;
  1539. X        }
  1540. X    }
  1541. X    else
  1542. X        if( create_flag ) mac = new_macro( name, expansion );
  1543. X
  1544. X    if( mac && !(mac->flags & MF_ADDED )) {
  1545. X        mac->flags |= MF_ADDED;
  1546. X        AddTail( &Global.macrolist, &mac->node );
  1547. X    }
  1548. X    return( mac );
  1549. X}
  1550. X
  1551. X/*    Set's the automatic variables $@ $* and $<  */
  1552. Xvoid
  1553. Xset_target_macros( char *tarname, char *depname )
  1554. X{
  1555. X    struct macro *mac;
  1556. X
  1557. X    if( tarname && *tarname ) {
  1558. X        char *dupname = strdup( tarname );
  1559. X        char *next;
  1560. X        if( dupname ) { /* try the more efficient way first */
  1561. X            next = strrchr( dupname, '.' );
  1562. X            if( next ) *next = (char)0; /* remove the extension */
  1563. X            mac    = set_macro( "*", dupname );
  1564. X            free( dupname );
  1565. X        }
  1566. X        else {
  1567. X            mac = set_macro( "*", tarname );
  1568. X            next = strrchr( mac->name, '.' );
  1569. X            if( next ) *next = (char)0; /* remove the extension */
  1570. X        }
  1571. X    }
  1572. X    else mac = set_macro( "*", NULL );
  1573. X    mac = set_macro( "@", tarname );
  1574. X    mac = set_macro( "<", depname );
  1575. X}
  1576. X
  1577. Xvoid
  1578. Xdelete_macrolist( struct List *list )
  1579. X{
  1580. X    for_list( list, delete_macro );
  1581. X    NewList( list );
  1582. X}
  1583. X
  1584. X/* set a variable by expanding all macros in its value */
  1585. Xstruct macro *
  1586. Xset_simplemacro( char *name, char *value )
  1587. X{
  1588. X    char *expansion = NULL;
  1589. X    struct macro *mac = NULL;
  1590. X
  1591. X    expansion = (char *)malloc( Param.MaxLine );
  1592. X    if( !expansion ) goto death;
  1593. X
  1594. X    if( expand_macros( expansion, value, Param.MaxLine )) goto death;
  1595. X    if( mac = set_macro( name, expansion )) {
  1596. X        mac->flags |= MF_SIMPLE;
  1597. X    }
  1598. Xdeath:
  1599. X    if( expansion ) free( expansion );
  1600. X    return( mac );
  1601. X}
  1602. END_OF_FILE
  1603. if test 3534 -ne `wc -c <'macro.c'`; then
  1604.     echo shar: \"'macro.c'\" unpacked with wrong size!
  1605. fi
  1606. # end of 'macro.c'
  1607. fi
  1608. if test -f 'main.c' -a "${1}" != "-c" ; then 
  1609.   echo shar: Will not clobber existing file \"'main.c'\"
  1610. else
  1611. echo shar: Extracting \"'main.c'\" \(4324 characters\)
  1612. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  1613. X/*    main.c
  1614. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1615. X *
  1616. X */
  1617. X
  1618. X#include <ctype.h>
  1619. X
  1620. X#include <exec/exec.h>
  1621. X#include <exec/execbase.h>
  1622. X
  1623. X#include <intuition/intuitionbase.h>
  1624. X#include <graphics/gfxbase.h>
  1625. X
  1626. X#include <clib/exec_protos.h>
  1627. X#include <clib/dos_protos.h>
  1628. X
  1629. Xextern struct GfxBase *GfxBase;
  1630. Xextern struct IntuitionBase *IntuitionBase;
  1631. X
  1632. X#include "make.h"
  1633. X#include "depend.h"
  1634. X
  1635. X/* Globals */
  1636. Xstruct globals Global = {
  1637. X    NULL,    /* me */
  1638. X    NULL,    /* logfile */
  1639. X
  1640. X    {
  1641. X    (struct Node *)&Global.targetlist.lh_Tail,    /* lh_Head */
  1642. X    (struct Node *)NULL,                        /* lh_Tail */
  1643. X    (struct Node *)&Global.targetlist.lh_Head,    /* lh_TailPred */
  1644. X    (UBYTE)NT_USER,
  1645. X    (UBYTE)0
  1646. X    },    /* targetlist */
  1647. X    {
  1648. X    (struct Node *)&Global.suffixlist.lh_Tail,    /* lh_Head */
  1649. X    (struct Node *)NULL,                        /* lh_Tail */
  1650. X    (struct Node *)&Global.suffixlist.lh_Head,    /* lh_TailPred */
  1651. X    (UBYTE)NT_USER,
  1652. X    (UBYTE)0
  1653. X    },    /* suffixlist */
  1654. X    {
  1655. X    (struct Node *)&Global.macrolist.lh_Tail,    /* lh_Head */
  1656. X    (struct Node *)NULL,                        /* lh_Tail */
  1657. X    (struct Node *)&Global.macrolist.lh_Head,    /* lh_TailPred */
  1658. X    (UBYTE)NT_USER,
  1659. X    (UBYTE)0
  1660. X    },    /* macrolist */
  1661. X    0    /* recursion level */
  1662. X};
  1663. X
  1664. Xstatic int
  1665. Xopen_libraries( void )
  1666. X{
  1667. X#ifndef _DCC
  1668. X    if( !( IntuitionBase = OpenLibrary( "intuition.library", 33 ))) {
  1669. X        return( 1 );
  1670. X    }
  1671. X    if( !( GfxBase = OpenLibrary( "graphics.library", 33 ))) {
  1672. X        return( 1 );
  1673. X    }
  1674. X#endif
  1675. X    return( 0 );
  1676. X}
  1677. X
  1678. Xstatic void
  1679. Xclose_libraries( void )
  1680. X{
  1681. X#ifndef _DCC
  1682. X    if( IntuitionBase )
  1683. X        CloseLibrary( IntuitionBase );
  1684. X
  1685. X    if( GfxBase )
  1686. X        CloseLibrary( GfxBase );
  1687. X#endif
  1688. X}
  1689. X
  1690. Xstatic int
  1691. Xnew_globals( struct globals *globptr )
  1692. X{
  1693. X    globptr->me = (struct Process *) FindTask( NULL ); /* find this task */
  1694. X    return( 0 );
  1695. Xdeath:
  1696. X    printf( "problem initializing globals\n" );
  1697. X    return( 1 );
  1698. X}
  1699. X
  1700. Xstatic int
  1701. Xdelete_globals( struct globals *globptr )
  1702. X{
  1703. X    memset( globptr, 0, sizeof(struct globals));
  1704. X
  1705. X    /*    just allow exit() to take care of free()ing all of our
  1706. X     *    allocations, because I don't feel like doing it right now
  1707. X     */
  1708. X    NewList( &globptr->targetlist );
  1709. X    NewList( &globptr->suffixlist );
  1710. X    NewList( &globptr->macrolist );
  1711. X}
  1712. X
  1713. X
  1714. Xstatic void
  1715. Xdie( void )
  1716. X{
  1717. X    delete_params();
  1718. X
  1719. X    close_logfile();
  1720. X
  1721. X    delete_globals( &Global );
  1722. X    close_libraries();
  1723. X}
  1724. X
  1725. Xstatic int
  1726. Xinit( void )
  1727. X{
  1728. X    if( open_libraries()) goto death;
  1729. X    if( new_globals( &Global )) goto death;
  1730. X
  1731. X    return( 0 );
  1732. Xdeath:
  1733. X    return( 1 );
  1734. X}
  1735. X
  1736. Xstatic long
  1737. Xdo_cl_macro( struct string_node *one )
  1738. X{
  1739. X    long retval;
  1740. X    int made;
  1741. X
  1742. X    if( strchr( one->data, '=' )) {
  1743. X        logprintf( "\t%s\n", one->data );
  1744. X        process_macroline( one->data );
  1745. X        Remove( &one->node );
  1746. X        delete_snode( one );
  1747. X    }
  1748. X    return( 0 );
  1749. X}
  1750. X
  1751. Xstatic long
  1752. Xrun_one( struct string_node *one )
  1753. X{
  1754. X    long retval;
  1755. X    int made;
  1756. X
  1757. X    debugprintf( 2, ("\n** run_one Make %s **\n", one->data ));
  1758. X    retval = (long) make_filename( one->data, &made );
  1759. X    if( !retval && !made ) {
  1760. X        logprintf( "\"%s\" is up to date\n", one->data );
  1761. X    }
  1762. X    return( retval );
  1763. X}
  1764. X
  1765. Xstatic void
  1766. Xrun_it( void )
  1767. X{
  1768. X    long retval;
  1769. X    int made;
  1770. X
  1771. X    if( Param.filelist.lh_Head->ln_Succ )
  1772. X        (void)for_list( &Param.filelist, do_cl_macro );
  1773. X    if( Param.filelist.lh_Head->ln_Succ ) {
  1774. X        (void)for_list( &Param.filelist, run_one );
  1775. X    }
  1776. X    else {
  1777. X        struct target *first_goal;
  1778. X        for( first_goal = (struct target *)Global.targetlist.lh_Head;
  1779. X            first_goal->node.ln_Succ;
  1780. X            first_goal = first_goal->node.ln_Succ ) {
  1781. X            if( !(first_goal->flags & (TF_SUFFIX|TF_BUILTIN ))) break;
  1782. X        }
  1783. X        if( first_goal->node.ln_Succ ) {
  1784. X            debugprintf( 2, ("\n** first_goal Make %s **\n",
  1785. X                first_goal->name ));
  1786. X            retval = make_filename( first_goal->name, &made );
  1787. X            if( !retval && !made ) {
  1788. X                logprintf( "\"%s\" is up to date\n", first_goal->name );
  1789. X            }
  1790. X        }
  1791. X    }
  1792. X    logprintf( "\tMake done.\n" );
  1793. X}
  1794. X
  1795. Xint
  1796. Xmain( int argc, char *argv[] )
  1797. X{
  1798. X    if( GfxBase->LibNode.lib_Version < 36L ) {
  1799. X        printf( "This program requires Amiga OS 2.0\n" );
  1800. X        return( 20 );
  1801. X    }
  1802. X
  1803. X    atexit( die );    /* add die() to normal exit procedure */
  1804. X
  1805. X    if( parse_parameters( argc, argv )) goto bailout;
  1806. X
  1807. X    logprintf( "%s\n", version_string+7 );
  1808. X    logprintf( "%s\n", copyright_string );
  1809. X
  1810. X    if( init() ) goto bailout;
  1811. X    if( init_builtins()) goto bailout;
  1812. X
  1813. X    if( Param.filelist.lh_Head->ln_Succ )
  1814. X        (void)for_list( &Param.filelist, do_cl_macro );
  1815. X
  1816. X    if( input_makefile( Param.makefile, 0 )) goto bailout;
  1817. X    if( Param.print_database ) dump_all();
  1818. X    else run_it();
  1819. X
  1820. X    return( 0 );
  1821. X
  1822. Xbailout:
  1823. X    /* die(); is called by atexit */
  1824. X    return( 20 );
  1825. X}
  1826. X
  1827. END_OF_FILE
  1828. if test 4324 -ne `wc -c <'main.c'`; then
  1829.     echo shar: \"'main.c'\" unpacked with wrong size!
  1830. fi
  1831. # end of 'main.c'
  1832. fi
  1833. if test -f 'make.h' -a "${1}" != "-c" ; then 
  1834.   echo shar: Will not clobber existing file \"'make.h'\"
  1835. else
  1836. echo shar: Extracting \"'make.h'\" \(3099 characters\)
  1837. sed "s/^X//" >'make.h' <<'END_OF_FILE'
  1838. X#include <exec/nodes.h>
  1839. X#include <exec/lists.h>
  1840. X#include <intuition/intuition.h>
  1841. X#include <dos/dos.h>
  1842. X#include <dos/dosextens.h>
  1843. X#include <stdio.h>
  1844. X#include <stdlib.h>
  1845. X#include <string.h>
  1846. X#include <stdarg.h>
  1847. X
  1848. X#ifndef MAXPATHNAME
  1849. X#define MAXPATHNAME    108
  1850. X#endif
  1851. X
  1852. Xstruct parameters {
  1853. X    struct List filelist;
  1854. X    int MaxLine;    /* maximum line length */
  1855. X    int verbosity;    /* 0 = silent */
  1856. X    int log;
  1857. X    int debug;
  1858. X    int touch_mode;
  1859. X    int all_mode;
  1860. X    int no_builtins;
  1861. X    int pretend_mode;
  1862. X    int print_database;
  1863. X    char *makefile;
  1864. X};
  1865. X
  1866. Xstruct globals {
  1867. X    struct Process *me;
  1868. X    FILE *logfile;
  1869. X
  1870. X    struct List targetlist;    /* target rules */
  1871. X    struct List suffixlist;    /* suffix rules */
  1872. X    struct List macrolist;    /* macros */
  1873. X
  1874. X    int recursion_level;
  1875. X};
  1876. X
  1877. Xstruct string_node {
  1878. X    struct Node node;
  1879. X    char data[2];
  1880. X};
  1881. X
  1882. X#define min(a,b)    (((a) < (b)) ? (a) : (b))
  1883. X#define max(a,b)    (((a) > (b)) ? (a) : (b))
  1884. X
  1885. X
  1886. Xextern struct parameters Param;
  1887. Xextern struct globals Global;
  1888. Xextern char version_string[];
  1889. Xextern char copyright_string[];
  1890. X
  1891. Xextern void NewList( struct List * );
  1892. Xextern char *basename( const char * );
  1893. X
  1894. X#define debugprintf(l,x) \
  1895. X    if( Param.debug && Param.verbosity >= (l)) logprintf x ;
  1896. X
  1897. Xint parse_parameters( int argc, char *argv[] );
  1898. Xvoid delete_params( void );
  1899. X
  1900. Xstruct string_node *new_snode( const char *str );
  1901. Xstruct string_node *renew_snode( const struct string_node *old, const char *str );
  1902. Xstruct string_node *delete_snode( struct string_node *old );
  1903. Xvoid delete_slist( struct List *list );
  1904. X
  1905. Xstruct void *for_list( struct List *list, long (*node_fn)(void *));
  1906. Xvoid attach_list( struct List *newlist, struct List *oldlist );
  1907. X
  1908. Xint help( void );
  1909. X
  1910. X/*
  1911. Xint prompt( BPTR tty, const char *str );
  1912. Xvoid tty_gotoxy( BPTR tty, int x, int y );
  1913. Xvoid tty_put( BPTR tty, char *str, long outsize );
  1914. Xvoid tty_puts( BPTR tty, char *str );
  1915. Xvoid tty_printf( BPTR tty, const char *fmt, ... );
  1916. Xvoid tty_clear( BPTR tty );
  1917. Xvoid tty_clear_eol( BPTR tty );
  1918. Xvoid tty_open_line( BPTR tty );
  1919. Xvoid tty_normal( BPTR tty );        
  1920. Xvoid tty_bold( BPTR tty );        
  1921. Xvoid tty_underline( BPTR tty );
  1922. Xvoid tty_backspace( BPTR tty );
  1923. Xvoid tty_scroll_up( BPTR tty, int lines );
  1924. Xvoid tty_scroll_down( BPTR tty, int lines );
  1925. X
  1926. Xint tty_getchar( void );
  1927. Xint hit_a_key( void );
  1928. Xvoid statusline( const char *s );
  1929. Xint get_string( char *buf, int mlen );
  1930. Xint get_number( char *buf, int mlen );
  1931. Xint get_valid_string( char *buf, int mlen, int (*validate)());
  1932. X*/
  1933. X
  1934. Xint open_logfile( void );
  1935. Xvoid close_logfile( void );
  1936. Xvoid logfile( char *string );
  1937. Xvoid logprintf( const char *fmt, ... );
  1938. X
  1939. Xlong doCommand( char *command, BPTR other );
  1940. Xlong xsystem( char *cmd );
  1941. X
  1942. Xint input_makefile( const char *makefile, int builtin_flag );
  1943. Xint make_filename( const char *goalname, int *made );
  1944. Xint get_directive_state( void );
  1945. X
  1946. Xchar *find_token( char *line, int tok );
  1947. Xint isemptyline( char *line );
  1948. Xchar *parse_strtok( char *dest, char *source, int len, int (*isdelim)( int ));
  1949. Xchar *parse_str( char *dest, char *source, int len);
  1950. Xint count_args(unsigned char *string);
  1951. Xchar *find_word( char *string, int word );
  1952. Xvoid strip_trailspace( char *line );
  1953. Xint isnotsuf( int ch );
  1954. X
  1955. Xint init_builtins( void );
  1956. END_OF_FILE
  1957. if test 3099 -ne `wc -c <'make.h'`; then
  1958.     echo shar: \"'make.h'\" unpacked with wrong size!
  1959. fi
  1960. # end of 'make.h'
  1961. fi
  1962. if test -f 'param.c' -a "${1}" != "-c" ; then 
  1963.   echo shar: Will not clobber existing file \"'param.c'\"
  1964. else
  1965. echo shar: Extracting \"'param.c'\" \(3663 characters\)
  1966. sed "s/^X//" >'param.c' <<'END_OF_FILE'
  1967. X/*    param.c
  1968. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  1969. X *
  1970. X */
  1971. X
  1972. X#include <ctype.h>
  1973. X#include <scdir.h>
  1974. X
  1975. X#include <clib/exec_protos.h>
  1976. X
  1977. X#include "make.h"
  1978. X
  1979. Xstruct parameters Param = {
  1980. X    {
  1981. X    (struct Node *)&Param.filelist.lh_Tail,    /* lh_Head */
  1982. X    (struct Node *)NULL,                    /* lh_Tail */
  1983. X    (struct Node *)&Param.filelist.lh_Head,    /* lh_TailPred */
  1984. X    (UBYTE)NT_USER,
  1985. X    (UBYTE)0
  1986. X    },    /* filelist */
  1987. X    1024, /* MaxLine */
  1988. X    1,    /* verbosity */
  1989. X    0,    /* log */
  1990. X    0,    /* debug */
  1991. X    0,    /* touch mode */
  1992. X    0,    /* all mode */
  1993. X    0,    /* no builtins */
  1994. X    0,    /* pretend mode */
  1995. X    0,    /* print database */
  1996. X    NULL /* makefile */
  1997. X};
  1998. X
  1999. Xconst char *usage_string =
  2000. X    "Usage: make -abdhnpt -v# +m# -fmakefile var=value wildcards...";
  2001. X
  2002. Xconst char *help_lines[] = {
  2003. X    "-a\t"    "make all dependents regardless of modification time",
  2004. X    "-b\t"    "do not use builtin rules",
  2005. X    "-d\t"    "debug mode (enable printf)",
  2006. X    "+m#\t"    "sets the maximum line length to # (minimum = 1024)",
  2007. X    "-n\t"    "prints commands to be executed, but do not execute them",
  2008. X    "-p\t"    "prints the database, but do not run",
  2009. X    "-t\t"    "make targets up to date by touching (commands not executed)",
  2010. X    "-v#\t"    "set verbose level to #; 0=silent",
  2011. X    "-fmakefile\t"    "specify the makefile to run",
  2012. X    "var=value\t"    "assigns the value to a variable",
  2013. X    "wildcards\t"    "specify specific targets to make",
  2014. X    NULL
  2015. X};
  2016. X
  2017. Xvoid
  2018. Xusage( void )
  2019. X{
  2020. X    puts( version_string+7 );
  2021. X    puts( usage_string );
  2022. X}
  2023. X
  2024. Xint
  2025. Xhelp( void )
  2026. X{
  2027. X    int i = 0;
  2028. X    char *helpline;
  2029. X
  2030. X    usage();
  2031. X    puts( copyright_string );
  2032. X    puts( "" );
  2033. X    while( helpline = help_lines[ i++ ] ) {
  2034. X        puts( helpline );
  2035. X    }
  2036. X
  2037. X    return( 0 );
  2038. X}
  2039. X
  2040. Xstatic int
  2041. Xexpand_wildcard( const char *wild )
  2042. X{
  2043. X    struct string_node *sptr = NULL;
  2044. X    char *fn;
  2045. X
  2046. X    while( fn = scdir( wild )) {
  2047. X        if( sptr = new_snode( fn )) {
  2048. X            AddTail( &Param.filelist, &sptr->node );
  2049. X        }
  2050. X        else return( 1 );
  2051. X    }
  2052. X    return( 0 );
  2053. X}
  2054. X
  2055. Xint
  2056. Xparse_parameters( int argc, char *argv[] )
  2057. X{
  2058. X    char *arg;
  2059. X
  2060. X    for( int i = 1; i < argc; i++ ) {
  2061. X        if( !(arg = argv[ i ] )) break;
  2062. X        switch( *arg ) {
  2063. X        case '-':
  2064. X            switch( *++arg ) {
  2065. X            default:
  2066. X            case '?':
  2067. X                usage();
  2068. X                goto death;
  2069. X            case 'V':
  2070. X                puts( version_string + 7);
  2071. X                puts( copyright_string );
  2072. X                goto death;
  2073. X            case 'a':
  2074. X                Param.all_mode = 1;
  2075. X                break;
  2076. X            case 'b':
  2077. X                Param.no_builtins = 1;
  2078. X                break;
  2079. X            case 'd':
  2080. X                Param.debug = 1;
  2081. X                break;
  2082. X            case 'f':
  2083. X                if( Param.makefile ) {
  2084. X                    puts( "only one -f argument is allowed" );
  2085. X                    goto death;
  2086. X                }
  2087. X                else {
  2088. X                    if( *++arg ) Param.makefile = strdup( arg );
  2089. X                    else if( ++i < argc ) {
  2090. X                        arg = argv[ i ];
  2091. X                        if( *arg ) Param.makefile = strdup( arg );
  2092. X                    }
  2093. X                }
  2094. X                break;
  2095. X            case 'h':
  2096. X                help();
  2097. X                goto death;
  2098. X            case 'n':
  2099. X                Param.pretend_mode = 1;
  2100. X                break;
  2101. X            case 'p':
  2102. X                Param.print_database = 1;
  2103. X            case 't':
  2104. X                Param.touch_mode = 1;
  2105. X                break;
  2106. X            case 'v':
  2107. X                Param.verbosity = atoi( ++arg );
  2108. X                break;
  2109. X            }
  2110. X            break;
  2111. X        case '+':
  2112. X            switch( *++arg ) {
  2113. X            case 'l':
  2114. X                Param.log = (Param.log) ? 0 : 1;
  2115. X                break;
  2116. X            case 'm':
  2117. X                {
  2118. X                    int maxline = atoi( ++arg );
  2119. X                    Param.MaxLine = max( Param.MaxLine, maxline);
  2120. X                }
  2121. X            }
  2122. X            break;
  2123. X        case '?':
  2124. X            usage();
  2125. X            goto death;
  2126. X        default: /* a filename */
  2127. X            if( scdir( arg ) ) {
  2128. X                scdir_abort();
  2129. X                if( expand_wildcard( arg )) goto death;
  2130. X            }
  2131. X            else {
  2132. X                struct string_node *sptr = new_snode( arg );
  2133. X                if( sptr ) {
  2134. X                    AddTail( &Param.filelist, &sptr->node );
  2135. X                }
  2136. X            }
  2137. X            break;
  2138. X        }
  2139. X    }
  2140. X    if( !Param.makefile ) Param.makefile = strdup( "Makefile" );
  2141. X
  2142. X    return( 0 );
  2143. Xdeath:
  2144. X    return( 1 );
  2145. X}
  2146. X
  2147. Xvoid
  2148. Xdelete_params( void )
  2149. X{
  2150. X    if( Param.makefile ) {
  2151. X        free( Param.makefile );
  2152. X        Param.makefile = NULL;
  2153. X    }
  2154. X    /* free Param */
  2155. X    delete_slist( &Param.filelist );
  2156. X    NewList( &Param.filelist );
  2157. X}
  2158. END_OF_FILE
  2159. if test 3663 -ne `wc -c <'param.c'`; then
  2160.     echo shar: \"'param.c'\" unpacked with wrong size!
  2161. fi
  2162. # end of 'param.c'
  2163. fi
  2164. if test -f 'parsing.c' -a "${1}" != "-c" ; then 
  2165.   echo shar: Will not clobber existing file \"'parsing.c'\"
  2166. else
  2167. echo shar: Extracting \"'parsing.c'\" \(2427 characters\)
  2168. sed "s/^X//" >'parsing.c' <<'END_OF_FILE'
  2169. X/*    Parsing.c
  2170. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  2171. X *
  2172. X */
  2173. X
  2174. X#include <string.h>
  2175. X#include <ctype.h>
  2176. X
  2177. X/*    Parse the first word from the source string into the dest string
  2178. X *
  2179. X *    return: pointer to next whitespace past parsed argument
  2180. X */
  2181. X
  2182. Xchar *
  2183. Xparse_strtok( char *dest, char *source, int len, int (*isdelim)( int ))
  2184. X{
  2185. X    register char *s, *d;
  2186. X    int i = 0;
  2187. X
  2188. X    s = source;
  2189. X    d=dest;
  2190. X    while( i < len && *s ) {
  2191. X        if( (*isdelim)( *s )) break;
  2192. X        *d++ = *s++;
  2193. X        i++;
  2194. X    }
  2195. X    *d=(char)0;
  2196. X    return s;
  2197. X}
  2198. X
  2199. X
  2200. Xstatic int
  2201. Xiswhite( int ch )
  2202. X{
  2203. X    return( isspace( ch ));    /* macro */
  2204. X}
  2205. X
  2206. X/*    Parse the first word from the source string into the dest string
  2207. X *
  2208. X *    return: pointer to next whitespace past parsed argument
  2209. X */
  2210. Xchar *
  2211. Xparse_str( char *dest, char *source, int len )
  2212. X{
  2213. X    while( isspace( *source )) source++;    /* skip whitespaces */
  2214. X    return( parse_strtok( dest, source, len - 1, iswhite ));
  2215. X}
  2216. X
  2217. X/*    Counts the number of words in the string */
  2218. Xint
  2219. Xcount_args( unsigned char *string )
  2220. X{
  2221. X    int count, sflag, prev;
  2222. X    register unsigned char *a = string;
  2223. X
  2224. X    prev = 1;
  2225. X    count = 0;
  2226. X    for( ; *a; a++ ) {
  2227. X        sflag = isspace( *a );
  2228. X        if( !sflag && prev ) count++;
  2229. X        prev = sflag;
  2230. X    }
  2231. X    return count;
  2232. X}
  2233. X
  2234. X/*    finds the position of a particular word in a string */
  2235. X/*    the first word is numbered 1 */
  2236. X/*    find_word( string, count_args( string )) == last_word */
  2237. Xchar *
  2238. Xfind_word( char *string, int word )
  2239. X{
  2240. X    int count, sflag, prev;
  2241. X    register char *a = string;
  2242. X
  2243. X    prev = 1;
  2244. X    count = 0;
  2245. X    for( ; *a; a++ ) {
  2246. X        sflag = isspace( *a );
  2247. X        if( !sflag && prev ) if( ++count == word ) return( a );
  2248. X        prev = sflag;
  2249. X    }
  2250. X    return( NULL ); /* not found */
  2251. X}
  2252. X
  2253. Xvoid
  2254. Xstrip_trailspace( char *line )
  2255. X{
  2256. X    char *cptr;
  2257. X
  2258. X    cptr = line + strlen( line ) - 1;
  2259. X
  2260. X    while( cptr >= line && isspace( *cptr )) {
  2261. X        *cptr-- = (char)0;
  2262. X    }
  2263. X}
  2264. X
  2265. Xint
  2266. Xisnotsuf( int ch )
  2267. X{
  2268. X    if( !ch || isspace( ch ) || ch == '.' ) return( 1 );
  2269. X    return( 0 );
  2270. X}
  2271. X
  2272. Xint
  2273. Xisemptyline( char *line )
  2274. X{
  2275. X    while( *line ) {
  2276. X        if( !isspace( *line )) return( 0 );
  2277. X        line++;
  2278. X    }
  2279. X    return( 1 );
  2280. X}
  2281. X
  2282. X/*    locate the next instance of a token that is not escaped by a backslash
  2283. X */
  2284. Xchar *
  2285. Xfind_token( char *line, int tok )
  2286. X{
  2287. X    char *delim = strchr( line, tok );
  2288. X    while( delim && *(delim-1) == '\\' ) {
  2289. X        delim = strchr( delim + 1, tok );
  2290. X    }
  2291. X    return( delim );
  2292. X}
  2293. X
  2294. Xvoid
  2295. Xshift_string_left( char *string, int shift )
  2296. X{
  2297. X    register char *d, *s;
  2298. X    char *end = string + strlen( string );
  2299. X
  2300. X    d = string;
  2301. X    s = string + shift;
  2302. X    while( s <= end ) {
  2303. X        *d++ = *s++;
  2304. X    }
  2305. X}
  2306. X
  2307. END_OF_FILE
  2308. if test 2427 -ne `wc -c <'parsing.c'`; then
  2309.     echo shar: \"'parsing.c'\" unpacked with wrong size!
  2310. fi
  2311. # end of 'parsing.c'
  2312. fi
  2313. if test -f 'rawcon.c' -a "${1}" != "-c" ; then 
  2314.   echo shar: Will not clobber existing file \"'rawcon.c'\"
  2315. else
  2316. echo shar: Extracting \"'rawcon.c'\" \(2784 characters\)
  2317. sed "s/^X//" >'rawcon.c' <<'END_OF_FILE'
  2318. X/*    rawcon.c
  2319. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  2320. X *    
  2321. X */
  2322. X
  2323. X#include <exec/types.h>
  2324. X#include <exec/nodes.h>
  2325. X#include <exec/memory.h>
  2326. X#include <exec/tasks.h>
  2327. X#include <exec/ports.h>
  2328. X#include <exec/execbase.h>
  2329. X#include <libraries/dos.h>
  2330. X#include <libraries/dosextens.h>
  2331. X#include <intuition/intuitionbase.h>
  2332. X#include <intuition/intuition.h>
  2333. X#include <workbench/startup.h>
  2334. X
  2335. X#include <clib/exec_protos.h>
  2336. X#include <clib/dos_protos.h>
  2337. X
  2338. X#include "make.h"
  2339. X
  2340. Xvoid
  2341. XSetRawMode( long flag )
  2342. X{
  2343. X    struct Process *process;
  2344. X    struct MsgPort *conport;
  2345. X    struct MsgPort *replyport;
  2346. X    struct StandardPacket *pkt;
  2347. X
  2348. X    if( !(process = Global.me )) return; /* find this task */
  2349. X    /* msgport for CON: */
  2350. X    conport = (struct MsgPort *) process->pr_ConsoleTask;
  2351. X
  2352. X    replyport=&process->pr_MsgPort;
  2353. X
  2354. X    pkt=(struct StandardPacket *) malloc(sizeof(struct StandardPacket));
  2355. X
  2356. X    pkt->sp_Msg.mn_Node.ln_Name=(char *) &pkt->sp_Pkt;
  2357. X    pkt->sp_Pkt.dp_Port=replyport;
  2358. X    pkt->sp_Pkt.dp_Type=994L;           /* set raw mode */
  2359. X    pkt->sp_Pkt.dp_Link=&pkt->sp_Msg;
  2360. X    pkt->sp_Pkt.dp_Arg1=flag;           /* TRUE for on, FALSE for off */
  2361. X
  2362. X    PutMsg(conport,&pkt->sp_Msg);
  2363. X    WaitPort(replyport);
  2364. X    Remove((struct Node *)&pkt->sp_Msg);
  2365. X
  2366. X    free(pkt);
  2367. X}
  2368. X
  2369. X/* findwindow.c - utility routine to find window of a CLI. */
  2370. Xstruct Window *
  2371. XFindWindow( BPTR file )
  2372. X{
  2373. X   extern struct DosLibrary *DOSBase;
  2374. X   struct Window *win;
  2375. X   struct Process *proc;
  2376. X   struct CommandLineInterface *cli;
  2377. X   struct InfoData *id;
  2378. X   struct StandardPacket *pkt;
  2379. X   struct FileHandle *fh;
  2380. X   long ret1,ret2;
  2381. X
  2382. X   if (id=(struct InfoData *)
  2383. X     AllocMem(sizeof(struct InfoData),MEMF_PUBLIC|MEMF_CLEAR)) {
  2384. X      if (pkt=(struct StandardPacket *)
  2385. X        AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) {
  2386. X         proc=(struct Process *) FindTask(NULL);
  2387. X         if (cli=(struct CommandLineInterface *) (proc->pr_CLI<<2)) {
  2388. X            ret1=cli->cli_ReturnCode;
  2389. X            ret2=cli->cli_Result2;
  2390. X            if (IsInteractive(file)) {
  2391. X               pkt->sp_Msg.mn_Node.ln_Name=(char *) &(pkt->sp_Pkt);
  2392. X               pkt->sp_Pkt.dp_Link=&(pkt->sp_Msg);
  2393. X               pkt->sp_Pkt.dp_Port=&(proc->pr_MsgPort);
  2394. X               pkt->sp_Pkt.dp_Type=ACTION_DISK_INFO;
  2395. X               pkt->sp_Pkt.dp_Arg1=((ULONG) id)>>2;
  2396. X               fh=(struct FileHandle *) (file<<2);
  2397. X               PutMsg(fh->fh_Type,(struct Message *) pkt);
  2398. X               WaitPort(&(proc->pr_MsgPort));
  2399. X               GetMsg(&(proc->pr_MsgPort));
  2400. X               win=(struct Window *) id->id_VolumeNode;
  2401. X            }
  2402. X            cli->cli_Result2=ret2;
  2403. X            cli->cli_ReturnCode=ret1;
  2404. X         }
  2405. X         FreeMem(pkt,sizeof(struct StandardPacket));
  2406. X      }
  2407. X      FreeMem(id,sizeof(struct InfoData));
  2408. X   }
  2409. X   return(win);
  2410. X}
  2411. X
  2412. END_OF_FILE
  2413. if test 2784 -ne `wc -c <'rawcon.c'`; then
  2414.     echo shar: \"'rawcon.c'\" unpacked with wrong size!
  2415. fi
  2416. # end of 'rawcon.c'
  2417. fi
  2418. if test -f 'readme' -a "${1}" != "-c" ; then 
  2419.   echo shar: Will not clobber existing file \"'readme'\"
  2420. else
  2421. echo shar: Extracting \"'readme'\" \(5098 characters\)
  2422. sed "s/^X//" >'readme' <<'END_OF_FILE'
  2423. X
  2424. X                         Readme For The Make Utility
  2425. X
  2426. X    Copyright (c) 1991 by Ben Eng
  2427. X
  2428. X    This program is free software; you can redistribute it and/or modify
  2429. X    it under the terms of the GNU General Public License as published by
  2430. X    the Free Software Foundation; either version 1, or (at your option)
  2431. X    any later version.
  2432. X
  2433. X    This program is distributed in the hope that it will be useful,
  2434. X    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2435. X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2436. X    GNU General Public License for more details.
  2437. X
  2438. X    You should have received a copy of the GNU General Public License
  2439. X    along with this program; if not, write to the Free Software
  2440. X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2441. X
  2442. X
  2443. X
  2444. XHOW TO CONTACT ME
  2445. X
  2446. X    Ben Eng
  2447. X    150 Beverley St. Apt #1L
  2448. X    Toronto, Ontario
  2449. X    M5T 1Y6
  2450. X    CANADA
  2451. X
  2452. X    telephone:  (416)-979-8761
  2453. X
  2454. X    e-mail:  ben@contact.uucp    or    uunet!mnetor!becker!contact!ben
  2455. X    BIX:     jetpen
  2456. X
  2457. X
  2458. XMANIFEST
  2459. X
  2460. X    README     -  This file
  2461. X    COPYING    -  The GNU General Public License
  2462. X    bmake      -  The binary executable for the Amiga running OS 2.0
  2463. X    bmake.doc  -  The documentation
  2464. X    less       -  utility for reading text files under Amiga OS 2.0
  2465. X
  2466. X    Makefile    \
  2467. X    builtin.c    \
  2468. X    dumprules.c  |
  2469. X    log.c        |
  2470. X    lists.c      |
  2471. X    param.c      |
  2472. X    snode.c      |
  2473. X    make.c       |
  2474. X    read.c       |__ Source code to the Make program
  2475. X    touch.c      |
  2476. X    input.c      |
  2477. X    expand.c     |
  2478. X    parsing.c    |
  2479. X    depend.c     |
  2480. X    fncall.c     |
  2481. X    main.c       |
  2482. X    macro.c      |
  2483. X    version.c    /
  2484. X    recipe.c    /
  2485. X                                     
  2486. X    makefile       \
  2487. X    builtin.c       \
  2488. X    depend.c         |
  2489. X    depend.h         |
  2490. X    dumprules.c      |
  2491. X    input.c          |
  2492. X    lists.c          |
  2493. X    log.c            |
  2494. X    macro.c          |
  2495. X    main.c           |__ Source code to the Make program
  2496. X    make.c           |
  2497. X    make.h           |
  2498. X    param.c          |
  2499. X    parsing.c        |
  2500. X    rawcon.c         |
  2501. X    recipe.c         |
  2502. X    snode.c          |
  2503. X    touch.c          |
  2504. X    tty.c           /
  2505. X    version.c      /
  2506. X                                                                
  2507. X    ben/basename.c \
  2508. X    ben/makefile    \__ Some files necessary to make ben.lib
  2509. X    ben/scdir.c     / 
  2510. X    ben/system.c   /
  2511. X
  2512. X    include/scdir.h  -- header file for the scdir routines
  2513. X
  2514. X
  2515. XABOUT THE PROGRAM
  2516. X
  2517. XThis program requires Amiga OS 2.0 or higher to run.  Run the program with
  2518. Xthe argument `?' to see its usage, or ``-h'' to get more descriptive help
  2519. Xon acceptable command line arguments.
  2520. X
  2521. XBecause the program was compiled with DICE 2.06.22, the heap memory
  2522. Xroutines directly perform an AllocMem() from the system memory pool.  The
  2523. XMake program performs many small allocations and deallocations, so it is
  2524. Xpossible for memory to become fragmented.  Hopefully, sophisticated heap
  2525. Xmemory routines will appear in the standard library to reduce memory
  2526. Xfragmentation.  I haven't noticed any problems with fragmentation though.
  2527. X
  2528. XThe environment variable ENV:system can be set to ``yes'' if you wish the
  2529. Xcommand execution to use the Amiga OS 2.0 System() call.  If ENV:system is
  2530. Xset to ``no'', the Amiga OS Execute() call is used instead.  The latter is
  2531. Xdesirable if you are still running with a shell that does not support the
  2532. X2.0 conventions (WShell 1.2 falls under this category).
  2533. X
  2534. XCommand line arguments to Make may not be grouped together; ``-a -n'' is
  2535. Xcompletely different from ``-an'' (which doesn't exist).
  2536. X
  2537. XThe present version of the Make program is incomplete and possibly
  2538. Xbug-ridden.  The documentation and functionality is incomplete, and
  2539. Xstill requires much work to be done.
  2540. X
  2541. XAs far as the author is concerned, because this software and documentation
  2542. Xis distributed free of charge, he is not obligated to provide any support
  2543. Xor updates.  However, the complete source code is provided, along with
  2544. Xenough information to construct an executable from it.  The author would be
  2545. Xvery appreciative of any comments, bug reports, and bug fixes that might be
  2546. Xprovided via paper mail and electronic mail (the addresses are provided
  2547. Xabove).
  2548. X
  2549. XIf there is something broken, first try to find an updated version of this
  2550. Xprogram.  If the bug still exists in the most recent version of the
  2551. Xprogram, please report it so that it can be fixed.  If you have fixed the
  2552. Xbug yourself, please provide me with the fixes so that they can be
  2553. Xincorporated into the next update.
  2554. X
  2555. XIf you actually use this program, I would like to know about it.  If I find
  2556. Xthat nobody uses it then I will not distribute future updates to it.  I
  2557. Xwrite programs that are useful to me, and I tend to distribute them if they
  2558. Xare useful to others.  I will only know that my programs are useful to
  2559. Xothers if they let me know that they use them.  Besides, I enjoy reading
  2560. Xwell-written mail.
  2561. X
  2562. XFeel free to send me things of little or great value, if it suits your
  2563. Xfancy.  Although this software is free (with respect to freedom) and no
  2564. Xfees are charged for its private use, I am not at all opposed to receiving
  2565. Xtokens of material wealth.
  2566. X
  2567. X[ And why do I have an 'If' in almost every sentence?  I think that I have
  2568. Xbeen programming too long today...  :-) ]
  2569. X
  2570. X    -Ben
  2571. X
  2572. END_OF_FILE
  2573. if test 5098 -ne `wc -c <'readme'`; then
  2574.     echo shar: \"'readme'\" unpacked with wrong size!
  2575. fi
  2576. # end of 'readme'
  2577. fi
  2578. if test -f 'recipe.c' -a "${1}" != "-c" ; then 
  2579.   echo shar: Will not clobber existing file \"'recipe.c'\"
  2580. else
  2581. echo shar: Extracting \"'recipe.c'\" \(1546 characters\)
  2582. sed "s/^X//" >'recipe.c' <<'END_OF_FILE'
  2583. X/*    recipe.c
  2584. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  2585. X *
  2586. X */
  2587. X
  2588. X#include <clib/exec_protos.h>
  2589. X#include <clib/dos_protos.h>
  2590. X
  2591. X#include <string.h>
  2592. X#include <ctype.h>
  2593. X
  2594. X#include "make.h"
  2595. X#include "depend.h"
  2596. X
  2597. X/* execute the command List to make a target */
  2598. Xint
  2599. Xrecipe( const char *goalname, struct List *cmdlist )
  2600. X{
  2601. X    char cd_string[ 10 ];
  2602. X    struct command *cmd;
  2603. X    char *expansion = NULL;
  2604. X    char *next;
  2605. X    int retval = 0;
  2606. X
  2607. X    if( !cmdlist ) return( 0 ); /* no command list */
  2608. X
  2609. X    if( Param.touch_mode ) {
  2610. X        logprintf( "\ttouch(%s)\n", goalname );
  2611. X        if( !Param.pretend_mode ) touch( goalname );
  2612. X        return( 0 );
  2613. X    }
  2614. X
  2615. X    expansion = (char *)malloc( Param.MaxLine );
  2616. X
  2617. X    for( cmd = (struct command *) cmdlist->lh_Head;    cmd->node.ln_Succ;
  2618. X        cmd = cmd->node.ln_Succ ) {
  2619. X        if( next = cmd->cmd )
  2620. X            while( isspace( *next )) next++;
  2621. X        if( next && *next ) {
  2622. X            if( expand_macros( expansion, next, Param.MaxLine )) {
  2623. X                logprintf( "Error expanding macros on commandline:\n"
  2624. X                    "\t%s\n", next );
  2625. X                break;
  2626. X            };
  2627. X            if( !(cmd->flags & CF_NOECHO ) || Param.debug )
  2628. X                logprintf( "\t%s\n", expansion );
  2629. X            parse_str( cd_string, expansion, 10 );
  2630. X            if( !strcmp( cd_string, "cd" )) {
  2631. X                logprintf( "the \"cd\" command does not work\n" );
  2632. X                break;
  2633. X            }
  2634. X            retval = (Param.pretend_mode ) ? 0 :xsystem( expansion );
  2635. X            if( retval ) {
  2636. X                char *s = (cmd->flags & CF_IGNORE ) ? "(Ignored)" : "" ;
  2637. X                logprintf( "command returned error %d %s\n", retval, s );
  2638. X                if( !(cmd->flags & CF_IGNORE )) break;
  2639. X            }
  2640. X        }
  2641. X    }
  2642. X    if( expansion ) free( expansion );
  2643. X    return( retval );
  2644. X}
  2645. END_OF_FILE
  2646. if test 1546 -ne `wc -c <'recipe.c'`; then
  2647.     echo shar: \"'recipe.c'\" unpacked with wrong size!
  2648. fi
  2649. # end of 'recipe.c'
  2650. fi
  2651. if test -f 'snode.c' -a "${1}" != "-c" ; then 
  2652.   echo shar: Will not clobber existing file \"'snode.c'\"
  2653. else
  2654. echo shar: Extracting \"'snode.c'\" \(1059 characters\)
  2655. sed "s/^X//" >'snode.c' <<'END_OF_FILE'
  2656. X/*    snode.c
  2657. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  2658. X *
  2659. X */
  2660. X
  2661. X#include <ctype.h>
  2662. X
  2663. X#include "make.h"
  2664. X
  2665. Xstruct string_node *
  2666. Xnew_snode( const char *str )
  2667. X{
  2668. X    struct string_node *new;
  2669. X    
  2670. X    if( new = malloc( sizeof(*new) + strlen( str ) )) {
  2671. X        strcpy( new->data, str );
  2672. X        new->node.ln_Name = new->data;
  2673. X        new->node.ln_Type = (UBYTE)NT_USER;
  2674. X        new->node.ln_Pri = 0;    /* Priority, for sorting */
  2675. X    }
  2676. X    return( new );
  2677. X}
  2678. X
  2679. Xstruct string_node *
  2680. Xrenew_snode( const struct string_node *old, const char *str )
  2681. X{
  2682. X    struct string_node *new;
  2683. X    
  2684. X    if( new = realloc( old, sizeof(*new) + strlen( str ) )) {
  2685. X        strcpy( new->data, str );
  2686. X        new->node.ln_Name = new->data;
  2687. X    }
  2688. X    return( new );
  2689. X}
  2690. X
  2691. Xstruct string_node *
  2692. Xdelete_snode( struct string_node *old )
  2693. X{
  2694. X    free( old );
  2695. X    return( NULL );
  2696. X}
  2697. X
  2698. Xvoid
  2699. Xdelete_slist( struct List *list )
  2700. X{
  2701. X    for_list( list, delete_snode );
  2702. X    NewList( list );
  2703. X}
  2704. X
  2705. X#ifdef DEBUG
  2706. Xint
  2707. Xprint_snode( struct string_node *old )
  2708. X{
  2709. X    printf( "snode: %s\n", old->data );
  2710. X    return( 0 );
  2711. X}
  2712. X
  2713. Xvoid
  2714. Xprint_slist( struct list *list )
  2715. X{
  2716. X    for_list( list, print_snode );
  2717. X}
  2718. X#endif
  2719. END_OF_FILE
  2720. if test 1059 -ne `wc -c <'snode.c'`; then
  2721.     echo shar: \"'snode.c'\" unpacked with wrong size!
  2722. fi
  2723. # end of 'snode.c'
  2724. fi
  2725. if test -f 'touch.c' -a "${1}" != "-c" ; then 
  2726.   echo shar: Will not clobber existing file \"'touch.c'\"
  2727. else
  2728. echo shar: Extracting \"'touch.c'\" \(2250 characters\)
  2729. sed "s/^X//" >'touch.c' <<'END_OF_FILE'
  2730. X/*    touch.c
  2731. X *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  2732. X *
  2733. X *    Update the modification time of a file to the present time.
  2734. X */
  2735. X
  2736. X#include <exec/memory.h>
  2737. X
  2738. X#include <clib/exec_protos.h>
  2739. X#include <clib/dos_protos.h>
  2740. X
  2741. Xextern struct MsgPort *CreatePort( UBYTE *name, long pri );
  2742. Xextern void DeletePort( struct MsgPort *io );
  2743. X
  2744. X#include <time.h>
  2745. X
  2746. X#include "make.h"
  2747. X
  2748. X/* return the current time */
  2749. Xtime_t
  2750. Xnowtime( void )
  2751. X{
  2752. X    struct DateStamp t;
  2753. X    time_t outtime = 0L;
  2754. X
  2755. X    DateStamp( &t );
  2756. X    outtime = t.ds_Tick/TICKS_PER_SECOND + 60*t.ds_Minute + 86400*t.ds_Days;
  2757. X    return( outtime );
  2758. X}
  2759. X
  2760. Xstatic long
  2761. Xdos_packet( struct MsgPort *port, long type, 
  2762. Xlong arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7 )
  2763. X{
  2764. X    struct StandardPacket *sp;
  2765. X    struct MsgPort *rp;
  2766. X    long ret;
  2767. X
  2768. X    if( !( rp = CreatePort( NULL, 0L ))) return( 1 );
  2769. X    if( !( sp = AllocMem( sizeof(*sp), MEMF_PUBLIC|MEMF_CLEAR))) {
  2770. X        DeletePort( rp );
  2771. X        return( 1 );
  2772. X    }
  2773. X    sp->sp_Msg.mn_Node.ln_Name = (char *)&sp->sp_Pkt;
  2774. X    sp->sp_Pkt.dp_Link = &sp->sp_Msg;
  2775. X    sp->sp_Pkt.dp_Port = rp;
  2776. X    sp->sp_Pkt.dp_Type = type;
  2777. X    sp->sp_Pkt.dp_Arg1 = arg1;
  2778. X    sp->sp_Pkt.dp_Arg2 = arg2;
  2779. X    sp->sp_Pkt.dp_Arg3 = arg3;
  2780. X    sp->sp_Pkt.dp_Arg4 = arg4;
  2781. X    sp->sp_Pkt.dp_Arg5 = arg5;
  2782. X    sp->sp_Pkt.dp_Arg6 = arg6;
  2783. X    sp->sp_Pkt.dp_Arg7 = arg7;
  2784. X    PutMsg( port, &sp->sp_Msg );
  2785. X    WaitPort( rp );
  2786. X    GetMsg( rp );
  2787. X    ret = sp->sp_Pkt.dp_Res1;
  2788. X    FreeMem( (void *)sp, sizeof(*sp) );
  2789. X    DeletePort(rp);
  2790. X    return( ret );
  2791. X}
  2792. X
  2793. X/*    update the modification time of a file */
  2794. Xvoid
  2795. Xtouch( const char *filename )
  2796. X{
  2797. X    struct MsgPort *task = NULL;
  2798. X    BPTR lock = (BPTR)0L;
  2799. X    BPTR plock = (BPTR)0L;
  2800. X    char *bcplstring = NULL;
  2801. X    struct DateStamp dateStamp;
  2802. X
  2803. X    if( !( bcplstring = (char *)AllocMem(64L, MEMF_PUBLIC))) goto death;
  2804. X    if( !( task = (struct MsgPort *)DeviceProc( filename ))) goto death;
  2805. X    if( !( lock = Lock( filename, SHARED_LOCK ))) goto death;
  2806. X    plock = ParentDir( lock );
  2807. X    UnLock( lock ); lock = NULL;
  2808. X
  2809. X    /* Strip pathnames first */
  2810. X    strcpy( bcplstring + 1, basename( filename ));
  2811. X    *bcplstring = (char)strlen(bcplstring + 1);
  2812. X
  2813. X    dos_packet( task, ACTION_SET_DATE, NULL, plock, (long)bcplstring >> 2,
  2814. X        (long) DateStamp( &dateStamp ), 0L, 0L, 0L);
  2815. X
  2816. Xdeath:
  2817. X    if( lock) UnLock( lock );
  2818. X    if( plock) UnLock( plock );
  2819. X    FreeMem((void *) bcplstring, 64L );
  2820. X}
  2821. END_OF_FILE
  2822. if test 2250 -ne `wc -c <'touch.c'`; then
  2823.     echo shar: \"'touch.c'\" unpacked with wrong size!
  2824. fi
  2825. # end of 'touch.c'
  2826. fi
  2827. if test -f 'version.c' -a "${1}" != "-c" ; then 
  2828.   echo shar: Will not clobber existing file \"'version.c'\"
  2829. else
  2830. echo shar: Extracting \"'version.c'\" \(155 characters\)
  2831. sed "s/^X//" >'version.c' <<'END_OF_FILE'
  2832. Xchar version_string[] = "\0$VER: Make 0.6 " __DATE__ " " __TIME__;
  2833. Xchar copyright_string[] = "Copyright " "\xa9" " 1991 by Ben Eng, All Rights Reserved";
  2834. X
  2835. END_OF_FILE
  2836. if test 155 -ne `wc -c <'version.c'`; then
  2837.     echo shar: \"'version.c'\" unpacked with wrong size!
  2838. fi
  2839. # end of 'version.c'
  2840. fi
  2841. if test -f 'wishlist' -a "${1}" != "-c" ; then 
  2842.   echo shar: Will not clobber existing file \"'wishlist'\"
  2843. else
  2844. echo shar: Extracting \"'wishlist'\" \(861 characters\)
  2845. sed "s/^X//" >'wishlist' <<'END_OF_FILE'
  2846. XWISHLIST
  2847. X
  2848. XHere are some features which I would like to implement in the future.
  2849. X
  2850. X-    :: rules to supply alternate rules for targets
  2851. X-    + command prefix to force the execution of lines
  2852. X-    force the execution of lines containing $(MAKE) or ${MAKE}
  2853. X-    the ``cd'' command
  2854. X-    the $^ automatic variable
  2855. X-    .DEFAULT .IGNORE .PHONY .PRECIOUS .SILENT
  2856. X-    pattern rules (eg., %.o: %.c) for greater flexibility
  2857. X-    static pattern rules
  2858. X-    replace all suffix rules with pattern rules
  2859. X-    the ability to apply rules to the contents of archives
  2860. X    and link libraries
  2861. X-    vpath and VPATH search paths for dependencies
  2862. X
  2863. X-    and as many of the functions listed in Chapter 9 of the manual to
  2864. X    GNU Make as humanly possible
  2865. X
  2866. X-    -W command line argument to run Make with a ``what if'' scenario
  2867. X-    parallel remote execution of compiles
  2868. X
  2869. X-    the ability to pass variables between nested executions of Make
  2870. X
  2871. X
  2872. END_OF_FILE
  2873. if test 861 -ne `wc -c <'wishlist'`; then
  2874.     echo shar: \"'wishlist'\" unpacked with wrong size!
  2875. fi
  2876. # end of 'wishlist'
  2877. fi
  2878. echo shar: End of archive 1 \(of 3\).
  2879. cp /dev/null ark1isdone
  2880. MISSING=""
  2881. for I in 1 2 3 ; do
  2882.     if test ! -f ark${I}isdone ; then
  2883.     MISSING="${MISSING} ${I}"
  2884.     fi
  2885. done
  2886. if test "${MISSING}" = "" ; then
  2887.     echo You have unpacked all 3 archives.
  2888.     rm -f ark[1-9]isdone
  2889. else
  2890.     echo You still need to unpack the following archives:
  2891.     echo "        " ${MISSING}
  2892. fi
  2893. ##  End of shell archive.
  2894. exit 0
  2895. -- 
  2896. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2897. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2898. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2899.